Question: What are some ways a SPO can attack the Cardano blockchain? E.g. in Bitcoin, a miner could intentionally exclude certain transactions to the extend that the miner's hash power allows. Is something like this possible in Cardano? What about other forms of attack? What discourages such attacks or mitigates the harm they can cause?

Answer: 
I am still researching if it is possible for a SPO to choose and exclude transactions when they are elected to create the block. I am pretty sure it isn't something you can just do 'out of the box,' I believe you would need to modify the client code of your block producer. With that said, **if** they could do that, it still wouldn't cause much damage. The reason why is because there is enough entropy built into the slot leader selection that the next block would pick up the excluded transaction. This is because it would be a new slot leader, thus only causing a ~20 second delay. This kind of attack is also discouraged because there is not incentive for just 1 pool operator to cherry pick (choose some, exclude others) transactions because the rewards are pooled and distributed at the end of the epoch. Meaning that if there were a lot of full-blocks, you could very slightly increase the overall rewards. However, after dividing it out to all the SPOs who created blocks, it likely wouldn't be worth your time. Now if multiple SPOs worked together on something like this, and we were constantly creating full blocks there could be incentive to choose the transactions that have larger fees (like ETH).
Decentralization is the mitigation against attacks in almost all of these systems, they all assume that a centralized player has not gained the power to control consensus.

An SPO could theoretically re-write their block producers software to do anything, like award themselves a million ADA. But it doesnt have any effect because no other SPOs agree that should happen.

Chain forks are probably the next thing an SPO could try to do, if they could create a dummy chain they could double-spend ADA. Ouroborous can withstand at least 6 blocks in any 22 blocks being created by attackers trying to fork the chain, and with 15 confirmations no users will be duped onto the wrong chain. It would be very hard for any SPO to co-ordinate more than 6 in 22 blocks becaise of the random nature of slot leader selection, unless they had a very high amount of stake and could wait for the the right time. Of course the problem there is that having a lot of stake on the system and damaging the system is stupid, because you are damaging your own value.

Forking is also dis-incentivized by the fact that all SPOs earn more if there are more successful blocks on the main chain. As rewards are held to the epoch end and distributed to SPOs based on the number of blocks they created on the main chain, its an incentive for all SPOs to find and stay on the main chain.