Нужно примерно так:
<xsl:if test="position() != last() and position() mod round(count(//group[@parent = $parent_id]) div 3) = 0">
Пояснение. В строке
round(count(//group[@parent = $parent_id]) div 3)
Мы считаем количество элементов в одном столбце, в данном примере это будет 15.
Далее мы смотрим остаток от деления текущей позиции на количество в одном столбце, как только он стал 0 - значит пора переводить столбце.
И заключительный штрих - чтобы после последнего столбца при полном заполнении не выводился еще один пустой столбец добавим
position() != last() and ...