In addition to what others have said, sometimes stuff gets added in a backwards compatible way. For example, Intel added two new instruction prefixes for their hardware lock elision extension. Actually, they reused existing instruction prefixes which were valid but did nothing on older CPUs when used on the instructions where the HLE prefixes apply. The semantics are such that "do nothing" is valid, but CPUs which understand the new prefix can do better.
Another alternative is to use the new instructions regardless, then trap illegal instructions and emulate them. This used to be a common way to handle floating point instructions, back in the days when FPU hardware wasn't universal. CPUs with FPUs would run the instructions natively, and CPUs without them would emulate them in software. This was, of course, unbelievably slow, but it worked.
But for the most part, you just generate different code for different CPU capabilities and dispatch, as the other comments describe.
Certainly the Borland 8087 emulation code used to have an interrupt call followed by the 8087 opcodes, the interrupt call got replaced at run time by NOPs if there was a co-processor present.
Another alternative is to use the new instructions regardless, then trap illegal instructions and emulate them. This used to be a common way to handle floating point instructions, back in the days when FPU hardware wasn't universal. CPUs with FPUs would run the instructions natively, and CPUs without them would emulate them in software. This was, of course, unbelievably slow, but it worked.
But for the most part, you just generate different code for different CPU capabilities and dispatch, as the other comments describe.