Why doesn't Core's GUI mark differently spent transactions?
It doesn't need to mark spent transactions, because once used, it doesn't need to track those transactions outputs anymore. It just store utxos for obvious reasons (block validation) in the
chainstate database.
Is there a simple way to check whether a TX(O) was spent?
Yes, just check they are no longer in the utxo database:
Unused:
$ bitcoin-cli gettxout 6c3695a0eabb70f9269b5117c94270cc74f1597814b9da7b312104b53ac2c13e 1
{
"bestblock": "00000000000000000027ac11adbd47fccb964c88e26ef94defb2d191ecc5f13d",
"confirmations": 10,
"value": 0.15515414,
...
}
Used (or non-existant):
$ bitcoin-cli gettxout 6c3695a0eabb70f9269b5117c94270cc74f1597814b9da7b312104b53ac2c13e 0
$