If you need to have an optional pattern at the end after an optional pattern (like .*?), you can convert the .*? lazy dot pattern into a tempered greedy token:
({\/\* )?#if ((?:(?! \*\/}).)*)( \*\/})?
See the regex demo.
The .*? is changed into a pattern that matches any char, zero or more but as many as possible occurrences, that is not a starting point of the */} char sequence.
Details:
({\/\* )? - an optional Group 1: /* and space
#if - an #if string
((?:(?! \*\/}).)*) - Group 2: any char other than line break chars, zero or more but as many as possible occurrences, that is not a starting point of the */} char sequence
( \*\/})? - an optional Group 3: */} string