TIL that there is something named
linker optimization that forces the deletion of unused functions in your final executable. As a bonus, you get the list of unused functions as compiler warnings (dead code is always bad, so you get the change to delete them or comment them out).
If you have a standard build system, do the following:
make CFLAGS="-ffunction-sections -fdata-sections" LDFLAGS="-Wl,--gc-sections -Wl,--print-gc-sections"