Question: I see that there are some benefits to conditional compilation using constructs like #ifdef over runtime conditional checks such as smaller compiled file size, probably faster execution, and somewhat easier debugging, but when is it appropriate to use one over the other? Is it a best practice to use runtime conditional checks when the conditional statement being evaluated can only be determined at runtime?

In my opinion mixing #ifdefs with regular if-then-else statements makes the code ugly and harder to read, so I tend to avoid conditional compilation. However I've noticed that in a lot of C# log class examples conditional compilation is used to determine when to perform logging depending on whether symbols such as DEBUG/SHIP/TRACE are defined.

Answer: 
It's best to minimise the use of #ifdef's. Like you said, they make the code harder to read and debug.

They can be unavoidable when targeting different platforms, or when there are differences between debug/release versions. 

Performance *could* be a consideration to use #ifdef's e.g. for debugging, but in most cases the impact of an extra conditional statement to check for log level would be negligible. I'd say you'd have to profile the code and determine that this is a bottleneck before converting conditional logic to #ifdef's
Conditional compilation should be used for things like compiling the same source code for different platforms or if you have different versions of a programm (for example a test version and a full version).