I get that Merkle trees make it easier to verify transactions, but I’m not totally clear on how they save space. So, if there are tons of transactions in a block and I just wanna prove one, do I only send the hashes up the branch? How much smaller is that compared to pulling the whole block?
Yes. To be exact, just the associated TX and TX hash of other TX on involved branch.
It's much smaller since AFAIK the data you need is only,
1. Block header (80 byte).
2. The transaction itself.
3. Total branch of the merkle tree multiplied by size of TXID (32 byte). For full block, i expect it'll have 13 branch which can store up to 8192 TX. So the size should be 416 bytes (13 x 32 byte).
Actually to prove one transaction in a block I think you only need your transaction data and a few "sibling" hashes from the Merkle tree to prove your transaction's inclusion to the root.
You don't actually need the hashes of other full transactions rather just the specific hashes needed for your branch. For a block with thousands of transactions this proof is really tiny probably only a few hundred bytes compared to the megabytes of the full block.