Here are some tips given to get the smallest code possible.
Find a better algorithm.
Use the -Os compiler switch.
Regroup global static variables in the same module which have the same size together to minimize the number of alignment directives (which increases the .bss and .data sections unnecessarily). Internally this is due to the fact that all static data is written to in the assembler file, in the order they are declared in the pascal source code.
Do not use the cdecl modifier, as this generates about 1 additional instruction after each subroutine call.
Use the smartlinking options for all your units (including the system unit).
Do not use ansistrings, widestrings and exception support, as these require a lot of code overhead.
Turn off range checking and stack-checking.
Turn off runtime type information generation.