My immediate guess on how to model it would be to create reified constraints for the wordlists of different lengths (the constraints in chapter 22 of https://www.gecode.org/doc-latest/MPG.pdf). For each square, use standard logical constraints to check if it is the start of a word (previous square a black one, this square not a black one), and how long the word is (using backwards counting of runs). These can be used to trigger the reified constraints above.
If the word-lists are short-ish enough, then an alternative for the above model would be to model the whole words using MDD or regular expression constraints, with an added control variable and setting all values as don't-care for the false case.
I my case, the black square positions are unknown, so the question instead is: "Given an empty crossword grid and a word list, does there exist a template allowing a feasible assignment of words for the grid?" Your intuition of how I modeled this is mostly correct, I used custom TABLE constraints for the words, that can be triggered on or off depending on the values of boolean variables.
I used CP-SAT to model this, and if you're interested in the technical side of things, I've discussed it in great detail here: https://pedtsr.ca/2023/generating-crossword-grids-using-cons...
It turns out that there are many weird complexities to take into account when the black square positions are unknown.
Another way to do it directly is to embed the control variable in the table, with a full set of all possible tuples for when the control variable is false. This, however, gives a large blow-up of the table size, especially for wide tables/long words and might be too expensive. Using compressed/smart/cartesian product tables or MDD constraints if the system supports it would solve this (OR-Tools does not, AFAIK).
As for the Gecode model, my idea was that the way to model the words using separate element constraint for each letter could reasonably be extended into a model for reified words by changing the element constraints to tables over the triple <control variable, index, letter> in the above way. The benefit is that one would not trigger the combinatorial blow-up one gets for the above with a full table over the whole word since it is only a single letter.
In a related case, I used reified extensional constraints specified using regular expressions in https://github.com/zayenz/cp-mod-ref-2019-patchwork to optionally place polyominoes on a grid.
Source: it me.
[0] https://www.youtube.com/watch?v=9aHfK8EUIzg [1] https://xd.saul.pw