I know that pool operators have the power to modify the actual blocks inside a transaction.
Transactions don't contain blocks. Miners/pool operators can't modify any of the normal transactions inside of a block. They can only change things in the block header, the coinbase transaction, and the transaction ordering.
I also know that pool operators can decide on block transaction orderings and even commit double spends pretty easily. I know that pool operators send the merkle root hash of this block to miners. The miner then provides the nonce, which is the hard work of mining.
Not necessarily. It depends on the protocol being used. If it is stratum, this is largely true (except the merkle root thing. Stratum only provides part of the merkle tree for the merkle root so that an extranonce in the coinbase can be used.)
If getblocktemplate is used, the miner has a lot of control over what is being hashed. With GBT, instead of just part of the header and hashed data being sent to the miner, the entire block structure is sent and the miner constructs the block and block header himself before hashing it. This means that the miner could choose to change whatever he wants in the block.
But, there's another part to mining, which is the block version number. Do most pool operators set this, for e.g. voting, and which bits are able to be set for votes?
If the pool is using stratum without ASICBOOST support, then the pool operator sets the bits for the miner. If ASICBOOST is supported, the miner can modify some of the bits in the version number in order to use ASICBOOST. With GBT, the miner can modify the version number if the pool indicates that they will accept a block with a version number different from the one that they set in the block template.
Also, note that miners do not vote. Setting the version number for soft forks is not a vote, it is signalling that the miner is prepared to enforce the rules of a soft fork. It is a signal of readiness, not a vote.