The most common way is to have the program enforce only part of the actual license algorithm. For example, say the license looks like this: UUUU-VVVV-WWWW-XXXX-YYYY-ZZZZ. The license algorithm might require the YYYY-ZZZZ part to have a particular structure. But as far as the program is concerned, any UUUU-VVVV-WWWW-XXXX part is permitted.
However, the manufacturer might choose the serial numbers in a testable way. For example,UUUU might identify the reseller, version, or product ID. VVVV-WWWW might be sequential to issue multiple licenses. But the XXXX part may be based on a secure hash of the UUUU-VVVV-WWWW part.
Since the secure hash is not implemented in the program or tested by it, it can be kept completely secret. All legitimate keys will have the correct secure hash, but keys with an invalid secure hash but a correct YYYY-ZZZZ part will work in the software, but must have been generated by a key generator.
Typically, the program will embed part of its key in things. In this example, likely the UUUU-VVVV-WWWW-XXXX-YYY part. This is enough to tell whose license it is (if it was legitimate) and whether it was generated by a keygen, but not enough to use the license to run the software.