You are correct, it is infact equivalent to knapsack problem. To the best of my knowledge most miners simply sort by fee and this gives a good approximation for optimal solution.
A couple of things of things to highlight how difficult the transaction slection is:
1) Knapsack problem as you pointed out.
2) But even if the constraint in knapsack were removed(i.e infinite blocksize), still calculating optimal fees is NP hard problem.
Transactions also have dependencies and conflicts. We’ll take
conflicts first, which come from the prohibition on double-spending.
We’ll also make the problem considerably easier by ignoring the block
size limit and assuming all transactions have a constant fee. If
transactions B and B’ both claim funds from transaction A, then only
one of B and B’ can be published and we say they conflict. If this is
the only constraint, we can simply draw a graph of all transactions
with edges between transactions which conflict. The miner’s task is to
find the largest set of vertices (transactions) with no edge between
then (no conflict). Solving this is exactly the maximum independent
set problem. (Source)
I presume the double-spend instances are rare and so are dependant transactions(child pays for parent known as CPFP). Therefore, my best guess is that simple greedy algorithm(taking CPFP into account) is close to optimal. Furthermore, there is also the tradeoff of time complexity which is very crutial for miners when we attempt alogrithms which are not simple.