The trick is that the compiler puts every function in a separate section in the .o file. Then the linker gets rid of the unused sections. That's all ;-) It is impossible to do the same thing with a.out object files, because the can contain only one .text section. ELF objects can contain any number of section, with arbitrary names. So we have to change our simple linker script for taking care of such cases.
I meant the opposite -- how it's possible even the ancient AtariST compilers (PureC, LatticeC, ... -- all used DRI/GST format I believe) discard unused stuff because it seems only natural thing to do and gcc/ld (from the beginning?) didn't care about it? It seemed strange to nobody? Or there was another (with the ability to discard unused stuff) object format mint community didn't choose to use? I just can't understand it.