JSFiddle - React, Tailwind, and code Playground

HTML

<code></code>

CSS

code {
  white-space: pre;
}

JavaScript

const data = `
..V..V.
V..V..V
.V..V..
..V..V.
V..V..V
.V..V..
..V..V.
`
const b = data.trim().split('\n').map((x, i) => x.trim().split('').map((x, j)=> x=='V' && ({i,j})))


const getBiggest = m => {
  let bestLength = 0
  let best = []
  for (let v of m.values()) {
    if (v.length > bestLength) {
      bestLength = v.length
      best = v
    }
  }
  return best
}
// the first element is a string representing the consumed (vertical|horizontal)lines
// encoded as lineIds:columnIds where lineIds and columnIds are bitmask
// second element is an array of taken Vs
const IDENTITY = ['0:0', []]
let m = new Map([IDENTITY])
let next
let best = null
for (const x of b.flatMap(y => y)) {
  if (!x) continue // not a V
  next = new Map(m.entries())
  for (const [key, values] of m) {
    const [lineId, columnId] = key.split(':').map(x => parseInt(x, 10))
    // intersection
    if ((2**x.i & lineId) !== 0 || (2**x.j & columnId) !== 0) {
      continue
    }

    const hash = [lineId | 2**x.i, columnId | 2**x.j].join(':')
    next.set(hash, values.concat(x))
  }

  m = next
}


const newBoard = b.slice(0).map(x => x.slice(0).map(x => typeof(x) === 'object' ? 'V' : '.'))
getBiggest(m).forEach(({i, j})=> newBoard[i][j] = 'X')

console.log(data)
console.log(newBoard.map(x => x.join('')).join('\n'))

const code = document.querySelector('code')
code.innerHTML += data
code.innerHTML += '\n'
code.innerHTML += newBoard.map(x => x.join('')).join('\n')