text:
Enklactify these strings
Inspired by this comment chain...

I wanna enklact my way out of this challenge but I can't...
@ETHproductions to enklact (v): to implement a lookup table using a subsection consisting of unique elements.

Enklacting is a very useful way to compress a lookup table. For example, let's say you had the following list of colors:
red
green
blue
yellow
purple
orange

If you want to be able to take a color as input and return it's index in this list, there's obviously the straightforward way:
["red", "green", "blue", "yellow", "purple", "orange"].index(input())

But there's a way we could do this in way less bytes:
"rgbypo".index(input()[0])

This works because the first (or 0'th) index of each string is unique. This example is obvious, but sometimes it's a little bit harder. What if we wanted to make a lookup table for this list?
Sweet Onion Chicken Teriyaki
Oven Roasted Chicken
Turkey Breast
Italian BMT
Tuna
Black Forest Ham
Meatball Marinara

In this case, we can't do this:
"SOTITBM".index(input()[0])

because there are two different inputs that start with a 'T', namely "Tuna" and "Turkey". We must look at a different index. If you look at the 4th index of each string, you'll notice that they are all unique. So we can do this...
"enklact".index(input()[3])

In this case, the "enklaction string" is "enklact".
That leads us to today's challenge...
Given a list of strings, return any valid enklaction string. Or in other words, given a list of strings, return any new string where each letter is unique, and the string is formed by joining the i'th letter of each string.
If there is no valid enklaction string, your submission must return an empty string or a consistent falsy value instead. As usual, either functions or full programs are allowed, and the input/output formats are permissive (within reason).
Each string will only contain printable ASCII, and this challenge is case sensitive.
This is code-golf, so try to write the shortest program possible in your language of choice!
Test cases
Input:
Programming
Puzzles
Code
Golf

Output (any one of these):
"ozdl"
"gzef"

Input:
the quick
brown fox
jumped over
lazy dogs

Output:
"tbjl"
"hrua"
"eomz"
" wpy"
"qne "
"if o"
"kxvs"

Note that "u dd" and "coog" are not valid.

Input:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Output:
""

Input:
AbC
aBc
bbC

Output:
"Aab"

Input:
@#$%^_
Hello_World
How are you?

Output:
"#eo"
"$lw"
"%l "
"^oa"

Input:
a
ab
ac

Output:
""

Can we return a list of valid strings?

@LyricLy Hmm, now that I think about it, that would have made more sense. But since there are already answers and it isn't too much boilerplate to return the first one, I'm going to say no, it should be any one valid string.

Can we guarantee none of the inputted strings are empty?

@musicman523 Yes.

Can we take input as an array of character arrays?

@Shaggy the default is "yes" Relevant meta

Can the consistent falsy value be an error of consistent type?

Excuse me, but I think the correct verb is enklactate.

@shaggy As far as I'm concerned, a character array is a string, so an array of characters arrays is perfectly fine.

@stewie I don't know... I feel like crashing instead of returning empty or false isn't really in the spirit.

Python 2, 68 67 61 bytes
lambda a:`{0:j for j in zip(*a)if len(set(j))==len(j)}`[6::5]

Try it online!
Improvements

From 68 bytes to 67 bytes by Jo King
From 66 to 65 bytes by Lynn

If output would not have to be a string:
Python 3, 49 bytes
lambda a:[j for j in zip(*a)if len({*j})==len(j)]

Try it online!

67 bytes

@JoKing Elegant and implemented.

I think max(`j`[2::5]for j in[""]+zip(*a)if len(set(j))==len(j)) works, to save a byte.

@Lynn thanks and updated.

Python3, 59 bytes
lambda l:{len({*d}):''.join(d)for d in zip(*l)}.get(len(l))

Returns a string with the enklact, None otherwise

Retina, 43 32 bytes
+/^(.).+^\1|^$/ms&m`^.

|""Lm`^.

Try it online! Edit: Saved 11 bytes thanks to @MartinEnder. Explanation:
+

Repeat while the input changes...
/^(.).+^\1|^$/ms&

...only if one line is empty or two lines begin with the same character...
m`^.

...delete the first character of every line. The repeat therefore stops if either a) all the lines begin with different characters, in which case the condition fails and the input does not get changed, or b) at least one line becomes empty, in which case all the characters eventually get deleted, at which point the input stops changing.
|""L`^.

Collect the first character of every line. (If there was no solution, the above loop will have deleted everything and there will be nothing to collect.)

Regex options also take regex modifiers (by writing them directly after the closing delimiter): https://tio.run/##K0otycxLNPz/P1dDP05DT1NPOy7GUD@3WDshTo@Ly7E4QU8rTkVPi6tGSckHKPT/f0BRfnpRYm5uZl46V0BpVVVOajGXc35KKpd7fk4aAA

Actually, that lets you get rid of the second stage entirely: https://tio.run/##K0otycxLNPz/X1s/TkNPU087LsawJk5FP7dYLTchTo@Lq0ZJyQfE@v8/oCg/vSgxNzczL50roLSqKie1mMs5PyWVyz0/Jw0A (somehow can't apply m with a group here, it looks like the conditional stage doesn't propagate the option).

Ah, of course, loop a conditional instead of a conditional loop, that solves the infinite loop bug in your first version. Very neat!

Haskell, 71 bytes
f x|elem""x=""|y<-head<$>x,and[filter(==a)y==[a]|a<-y]=y|1<2=f$tail<$>x

Try it online!
BMO saved 3 bytes with any null x → elem""x.
Ørjan Johansen saved a byte with sum[1|b<-y,a==b]<2 → filter(==a)[y]==[a].
Explanation
f x|elem""x=""                      -- Once any of the strings is empty, return "".
   |y<-head<$>x                     -- Otherwise, let y be all the first letters...
   ,and[                 |a<-y]     -- If, for all a in y,
        filter(==a)y==[a]           -- a occurs just once in y:
                               =y   -- return y.
   |1<2=f$tail<$>x                  -- Else, chop off all the first letters and recurse.

If throwing an error (Prelude.head: empty list) when there's no solution is OK, |elem""x="" can be erased for 61 bytes.

Shorter test: filter(==a)y==[a]

Pyth, 6 bytes
>1{I#C

Test suite.
The output is a singleton list, as allowed by default; the list [ ] (empty list, falsy) is returned in case the string cannot be enklactified.
Explanation

>1{I#C – Full program.
     C – Transpose the input, cropping absences.
    #  – Filter by:
  {I   – Invariant under deduplication.
>1     – Slice to 1. list[:1] in Python.

Pyth, 5 bytes
This would've been valid if crashing would have counted as a falsy value.
h{I#C

Test suite.

Ruby, 38 bytes
->x,*y{x.zip(*y).find{|z|z==z-[p]|[]}}

Try it online!
Thanks to G B for pointing out a bug.

Fails if there is no match and the first string is not the shortest.

@GB Could you provide an example, please? I modified my last test according to your description, and it worked.

Try ["abc", "ac", "acd"]

Now I see, you're right. Should be fixed.

Jelly, 7 bytes
z0Q€fZḢ

Returns the integer 0 if the strings cannot be enklactified.
Try it online!
How it works
z0Q€fZḢ  Main link. Argument: A (string array)

z0       Zip/transpose, filling shorter rows with 0.
  Q€     Unique each deduplicate resulting string.
     Z   Zip/transpose, without using a filler.
    f    Filter; keep only string that appear in the results to both sides.
      Ḣ  Head; extract the first string. Returns 0 if the array is empty.

Haskell, 76 74 bytes
f t=last$"":(id=<<foldr(zipWith(#))([[]]<$t)t)
x#[s]=[x:s|all(/=x)s]
x#e=e

Try it online! Returns the last valid lookup string or an empty string if no such string exists.

71 69 bytes
If throwing a consistent exception as falsy value is allowed:
f t=head$id=<<foldr(zipWith(#))([[]]<$t)t
x#[s]=[x:s|all(/=x)s]
x#e=e

Try it online! Throws an empty list exception if no string is found, returns the first valid string otherwise.
-2 bytes thanks to Ørjan Johansen

notElem x  can be shortened to all(/=x).

R, 116 107 95 bytes
R+pryr

pryr::f(for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
break}))

Try it online!
base R

function(v)for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
v=0})

Try it online!
These two variants saving 9 bytes thanks to Giuseppe.
Explanation:
This effectively truncates all stings in the vector v to the length of the shortest and iterates through subsequent indexes. Then checks whether there are any duplicates within chosen letters and if not, pastes them together and prints with cat. If all indexes return duplicated results, this prints empty string.
All wraped in an anonymous pryr function with break to halt the loop, or base R function zeroing the vector to break the loop.

Nice one! This can be golfed to 107 bytes in R+pryr or 107 bytes in base R.

Perl 5 -plF, 56 bytes
Saved 5 bytes thanks to @Xcali!
map$;[$_].=$F[$_],0..@F}{($_)=grep$.==y///c*!/(.).*\1/,@

Try it online!

Using $. instead of $- can save 5 bytes: Try it online!

@Xcali of course! That's great, thank you!

Japt v2.0a0, 7 bytes
Takes input as an array of character arrays strings, returns an array of characters a string or undefined.
ÕæÈ¶¸¬â

Try it

I tried the challenge out before reading your solution and got a nearly identical solution: z æ_¬eZ¬â

Exactly identical, other than the input format.

Stax, 9 8 bytes
åτIⁿs↓µg

Run and debug it
Explanation (unpacked):
M{c0-u=}j Full program, implicit input
          e.g. ["Programming", "Puzzles", "Code", "Golf"]
M         Transpose
                ["PPCG", "ruoo", "ozdl", "gzef", "rl\0\0", "ae\0\0", "ms\0\0", "m\0\0\0", "i\0\0\0", "n\0\0\0", "g\0\0\0"]
 {     }j Find first matching element:
            e.g. "PPCG"
  c0-       Copy and remove zero bytes (padding)
                 "PPCG" "PPCG"
     u      Unique
                 "PPCG" "PCG"
      =     Check if equal:
                 1
          First matching here: "ozdl". If none is found, the stack is empty
          Implicit output if anything on stack

R, 127 bytes
function(S,s=sapply(S,substring,x<-1:max(nchar(S)+1),x))cat(rbind(s[!apply(s,1,anyDuplicated)&!rowSums(s==""),],"")[1,],sep="")

Try it online!
sapply typically returns a matrix when all the length(FUN(X[[i]])) are equal, except when length(FUN(X[[i]]))==1, in which case it returns a vector. In order to use the matrix operations, then, we have to substring one further than we need to guarantee a matrix, which is why x extends to max(nchar(S)+1).
We then filter for rows that have no duplicates and no empty strings. Since we can only return a single string, we take the first one, except that when there are no rows that meet the criteria, we would throw an error, so we append an extra row of "" to the end.
Then we print out the enklactified string or the empty string.

Perl 6, 27 bytes
{([Z] $_).first:{.Set==$_}}

Try it online!
After seeing that the ruby version has been upvoted, I have copied the approach and used character lists, instead of strings. I don't like it.
My older, and more correct submission is as below:
Perl 6, 38 bytes
Split, zip, check uniqueness, join.

{[~] ([Z] @_>>.comb).first:{.Set==$_}}

Try it online!

05AB1E, 7 bytes
øʒDÙQ}н

Try it online!
Explanation
ø        # Zip the input array
 ʒ   }   # Filter by ...
  DÙQ    # ... an entry is equal to itself deduplicated
      н  # Take the first element

Python 3, 75 bytes
def f(t):c=[s.pop(0)for s in t];return all(t)and(f(t),c)[len(t)==len({*c})]

Operates on character lists instead of strings. Returns False if no valid enklaction string exists.
Try it online!

I think this recurses, which would make it invalid unless the f= is included in the byte count.

@LyricLy Fixed :)

Wolfram Language (Mathematica), 54 bytes
#&@@Select[PadRight@#,#~FreeQ~0&&Union@#==Sort@#&]&

Try it online!
Takes a list of list of characters as input, returns a list of characters. Contains U+F3C7, corresponding to "Transpose" operator.
Returns #1 and throws a bunch of ignorable errors when there is no suitable string.
Explanation:
PadRight@#

Pad the input so that each "string" (list of characters) is the same length. This appends integer 0s (not string "0"s). Then transpose.
Select[ ... ,#~FreeQ~0&&Union@#==Sort@#&]

Select the strings that have no integer 0s in them and have all unique characters.
#&@@

Get the first one.

Charcoal, 23 21 bytes
-2 bytes thanks to @Neil!
§ΦＥ⌊ＥθＬι⭆θ§λι⬤ι⁼¹№ιλ⁰

Try it online!

Huh, when did a) q stop always being a string b) StringMap start working on non-strings? Anyway, your Range is unnecessary, saving you 2 bytes.

@Neil a) When I added array/object input b) >_> I'm not sure. probably around the time when I fixed the while loop (sorry, forgot to mention either of those)

C (gcc), 161 bytes
f(s,i)char**s;{char**t,a[255],*u=a;for(i=0;memset(a,0,255),u&&~i;i+=!!~i&&u)for(t=s;(u=u?*t++:0)&&~(i=u[i]?i:-1)&&!a[u[i]]++;);while(~i&&(u=*s++))putchar(u[i]);}

Try it online!
Each character position is tested for duplication and skipped if a duplicate is detected; this is continued until the shortest string ends. It's ASCII only, sadly: DBCS/UTF-8 strings break this function badly!

152 bytes

Japt, 12 bytes
Returns undefined for non-enklactic strings.
y ·æ_¬n ä¦ e

Try it online!
Explanation:
y ·æ_¬n ä¦ e
y             // Split the input at newlines and transpose
  ·           // Join on newlines
   æ_         // Return the first item that returns truthy when ran through:
     ¬n       //   Sort
        ä¦    //   Reduce with !=
           e  //   All items are truthy (unique)

You should be able to save 2 bytes by taking input as an array of character arrays and ditching the two splits.

JavaScript (ES6), 66 bytes
Returns either a string or undefined if no solution exists.
f=(a,i=0)=>a.every(s=>(o[k+=c=s[i],c]^=1)&&c,o=k=[])?k:c&&f(a,i+1)

Try it online!
Commented
f = (           // f = recursive function taking:
  a,            //   a[] = input array
  i = 0         //   i   = pointer
) =>            //
  a.every(s =>  // for each string s in a[]:
    (o[k +=     //   append to the key string k
      c = s[i], //   the character c at position i in s
      c] ^= 1   //   and toggle o[c] (undefined -> 1 -> 0)
    ) && c,     //   additionally, make sure that c is defined
    o = k = []  //   start with o = k = empty array
  ) ?           // every() is true if all characters were distinct and defined:
    k           //   in which case we return k
  :             // else:
    c &&        //   provided that every() didn't fail because of an undefined character,
    f(a, i + 1) //   try again at the next position

Husk, 9 bytes
ḟS=UḞz:∞ø

Try it online!
Explanation
fS=UḞz:∞ø
    Ḟz:∞ø  Transpose the input dropping characters of longer strings
    Ḟ        Fold right
     z:      Zip with prepend
       ∞ø    Infinite list of empty lists
ḟS=U       Find the first string without duplicates, returns an empty string if none
ḟ            Return first value satisfying predicate
  =          Equal
 S U         to itself with duplicates removed

Using ←ġLT over Ḟz:∞ø should save a byte.

Retina, 81 56 bytes
m`$
$.=*£¢
N$`.
$.%`
¶

~`(.*?¢)+
L`.{$#1}
A`(.).*\1|£|¢

Try it online!
-25 bytes thanks to @Neil

Transposing rectangular text in Retina is surprisingly difficult.

I wish I knew a better way of performing rectangular transposition, but in the mean time, save 25 bytes.

@Neil Ahh... eval stage. I always forget retina 1.0 has all these cool new features

C (gcc), 121 113 110 bytes
i;d;f(s)char**s;{char**_=s,x[255]={0},y[99]={0};for(d=i=0;*_;)d+=x[y[i++]=*(*_++)++]++;d=d?*x?0:f(s):puts(y);}

Try it online!
Ungolfed
void enklactify(char *strings[]) {
    int quit = 0;
    while (!quit) {
        char **arg = strings;      // current row
        int exists[255] = {0};     // which characters exist in the column
        char output[99] = {0};     // will hold output string
        int index = 0;             // where to insert in output
        int duplicates = 0;        // have we found any duplicates?
        while (*arg != NULL) {
            char *word = *arg;     // current word
            char first = *word;    // first letter of current word
            if (exists[first])
                duplicates = 1;    // we found a duplicate
            exists[first] = 1;     // mark it as in our string
            output[index] = first; // add it to our output
            index++;
            (*arg)++;              // advances the current word to the next
                                   // character by reference (chops first char)
            arg++;                 // advance to next whole argument
        }

        if (!duplicates) {         // This is a valid solution
            puts(output);
            quit = 1;
        }

        if (exists[0]) {           // We hit the null terminator of one of the
                                   // input strings, so we failed
            quit = 1;
        }
    }
}

-3 thanks to ceilingcat
This abuses the ability to just add 1 to a string pointer in C to get the 'tail' of the string. The main byte savers are:

d+=x[y[i++]=*(*_)++]++ which appends the first character of the first string of _ to y, advances the first string of _ to remove its first character, adds the x entry at that character to d, and increments said x entry
q=d?*x:puts(y) which prints y if d is non-zero while setting q to a non-zero value, or sets q to non-zero if the first element of x is non-zero (if we were at the end of one of the strings then said element would be non-zero)

Edit: Shaved bytes by switching from while loop to recursive tail call and removing brackets from for loop.

Suggest for(d=i=0;*_;) instead of for(d=0,i=0;*_;++_) and *(*_++)++]++;d=d?!*x*f(s) instead of *(*_)++]++;d=d?*x?0:f(s)

Husk, 8 bytes
ḟȯ=L¹LUT

Try it online!
Different approach to the previous Husk answer.  Gets the longest prefix with all-unique characters from each index position, and then selects the first that is the same length as the number of input strings.
ḟ           # first element that satisfies
 ȯ=L¹L      # length (of string) equals length of input (array), of
      U     # longest prefixes of all unique characters of
       T    # transpose of input

Looks like the other answer is also 8 bytes using the golf in the comments.

@Razetime - yes, I noticed that, too.  So I don't claim to be better, just different...

ḟS=uT would be shorter, no?

@Razetime - unfortunately, that gives output for the test cases that shouldn't have a solution...

Pyth, 13 bytes
e+kf{IT@.TQ.t

Try it here
e+kf{IT@.TQ.t
           .tQ   Transpose the (implicit) input with padding.
        .TQ      Transpose the input without padding.
       @         Take the strings in both.
   f{IT          Find the ones that have no duplicates.
e+k              Get the last, or an empty string.

It seems that returning a list of all valid strings is not valid.

@LyricLy Fixed.

Red, 139 bytes
func[b][m: length? first b foreach a b[m: min m length? a]repeat n m[c: copy[]foreach a b[append c a/(n)]if c = unique c[return rejoin c]]]

Try it online!
Explanation:
Takes the input as a block (list) of strings. Returns the enklaction string or none otherwise.
f: func[b][
    m: length? first b                   ; the minimal length of the first string
    foreach a b[m: min m length? a]      ; find the minimal length of all strings
    repeat n m[                          ; limit the search to the minimal length
        c: copy[]                        ; an empty block
        foreach a b[append c a/(n)]      ; for each string append the current char
        if c = unique c[return rejoin c] ; if all chars are unique, return the block
    ]
]

APL+WIN, 35 33 bytes
2 bytes saved thanks to Adám
Prompts for the lines of text as a character matrix:
⊃((↑⍴¨a)=+/¨((a⍳¨a)=⍳¨⍴¨a))/a←,⌿⎕

Try it online! Courtesy of Dyalog Classic
Explanation:
a←,⌿⎕ prompts for input and creates a nested vector of the input matrix columns

((a⍳¨a)=⍳¨⍴¨a) creates a binary vector for each nested element with a 1 for each unique element

((↑⍴¨a)=+/¨ sums each binary vector and compares to number of characters in each element

(...)/a←⊂[1]⎕ selects only those elements where number of uniques = column length

⊃ converts nested vector back to a matrix of each valid enklaction string

⊂[1] → ,⌿

Röda, 80 77 bytes
f a{a|seq 0,#_|try{{|i|a|[_[i:i+1]]|orderedUniq|concat|[_]if[#_1=#a]}_|head}}

Try it online!
-1 byte thanks to Cows quack
Explanation:
f a{
  a|         /* Push the strings in a to the stream */
             /* For each string (_): */
  seq 0,#_|     /* Push a range from 0 to the length of _ to the stream */
  try{       /* Ignore errors during the following block */
    {|i|        /* For each i in the stream: */
      a|           /* Push strings in a to the stream */
      [_[i:i+1]]|  /* For each string, push the ith character to the stream */
      orderedUniq| /* Remove duplicate characters */
      concat|      /* Join the characters into a string */
      [_]if        /* Push the string to the stream if */
      [#_1=#a]     /* Its length is the length of a */
    }_|
    head        /* Take the first string in the stream and return it */
  }
}

The try keyword is used to dismiss errors that occur if i is larger than the length of the smallest string in a, or there is no answer and head causes an error.

You can remove the parens in seq to save a byte

C# (.NET Core), 167 bytes (149 + 18 for using System.Linq;)
p=>{int l=p.Count(),m=p.Min(s=>s.Length);for(int i=-1;i++<m;){var d=p.Select(s=>s[i]).Distinct();if(d.Count()==l)return string.Join("",d);}return"";}

Try it online!

Java 10, 106 bytes
a->{for(int i=0;;i++){var r="";for(var s:a)r+=s[i];if(r.length()==r.chars().distinct().count())return r;}}

Will give an error instead of returning an empty String if no solution can be found. Input is a character-matrix.
Try it online.
Explanation:
a->{                  // Method with character-matrix parameter and String return-type
  for(int i=0;;i++){  //  Loop `i` upwards
    var r="";         //   Result-String, starting empty
    for(var s:a)      //   Loop over the character-arrays of the input
      r+=s[i];        //    And append every `i`'th character to `r`
    if(r.length()==r.chars().distinct().count())
                      //   If `r` only contains unique characters
      return r;}}     //    Return `r` as result

OP didn't seem to want to allow errors, although admittedly never put it in the post itself.

Clojure, 59 bytes
#(for[s(apply map list %):when(=(count(set s))(count %))]s)

Returns a list of lists of characters.

Scala, 97 bytes
l=>l.flatMap(h=>(0 to l.map(_.size).min-1).find(i=>l.map(_(i)).toSet.size==l.size)map(h))mkString

input is List[String] and returns an empty String if no solution found.
Try it online.
Explanation:
l                                    // List("Programming", "Puzzles", "Code", "Golf")
  .flatMap(                          //
    h =>                             // "Programming"
      (0 to l.map(_.size).min-1)     // Range(0, 3) range from 0 to size of smallest word ("Code".size - 1 = 3)
        .find(                       // returns an Option[Int]: if for a given index, all words have a different char, return Some(i)
          i =>                       // index in words, let's say i = 2
            l.map(_(i)).toSet.size   // Set('o', 'z', 'd', 'l').size = 4; checks the nbr of unique chars for the given index
              == l.size              // and compare it to the nbr of words (4)
        )                            //
        map(h)                      // Option(i).map(i => h(i)) which gives Some(2).map(h) = Some('o') and for another index: None.map(h) = None; this is why the begining is l.flatMap and not l.map.
  )mkString                         // joins the List[Char] into a String

Hello and welcome to the site.  I don't know scala but this seems that this takes input from a predefined variable. This is not an accepted form of output.  It looks like you can probably fix this by adding l=>.

@WhatWizard Wasn't sure which convention to use to define the core of the code. I hope that's better.

Thunno 2 ch, 4 bytes
ṬæU:

Try it online!
Uses [] as the consistent falsy value. If we could output a list of all possible outputs, the h flag wouldn't be needed.
Explanation
ṬæU:  # Implicit input
Ṭ     # Transpose the input
 æ    # Filter this list by:
   :  #  Invariant under:
  U   #   Deduplicating?
      # Get the first item
      # (or [] if it's empty)
      # Implicit output


text:
Word Search on a Torus
The Challenge
Given a list of words and a grid of letters, your job is to determine which of the given words can be found on the grid in all 8 directions (forward, backward, up, down, and the 4 diagonal directions), much like a word search. The grid is toroidal, so the grid wraps around on the edges. Letters can be reused with this wrap-around property.
Wrapping around for diagonals behaves as you might expect. On a 4x6 grid going diagonally down and right, you would expect movement to look like this:
9 . 5 . 1 .
. . . 6 . 2
3 . . . 7 .
. 4 . . . 8

For an example of a wrap-around reuse word:
S E A H O R

Would be able to make SEAHORSE
Example Test Cases
Given this grid and the word list [ANT, COW, PIG]:
A N T
W C O
P G I

The result would be [ANT, COW, PIG]

Given this grid and the word list [CAT, DOG, DUCK, GOOSE, PUMPKIN]:
N O O D M E
O I O C U U
P G K O T C
K A U P S K

The result would be [DOG, DUCK, PUMPKIN]

Given this grid and the word list [TACO, BEEF, PORK]:
T A C B
A P O R
K E E F
B F C P

The result would be an empty list

Given this grid and the word list [ACHE, ASK, BAD, BOOK, COOK, CROW, GAS, GOOD, LESS, MARK, MASK, MEAL, SAME, SEAHORSE, SELL, SHOW, SLACK, WOOD]:
G S L A C K
H A E S R O
C M S K O O
A K S D W B

The result would be [ASK, BOOK, COOK, CROW, GAS, GOOD, LESS, MASK, SEAHORSE, SHOW, SLACK]

Given this grid and a list of all English words that are at least 3 letters long:
A R T U P
N T U B O
E S R O H
Q E T I U
E A T D P

The result would be [AEQ, AES, ANE, ART, ARTS, ATRIP, BOID, BON, BREE, BUD, BUT, DUB, DUE, DUET, EAN, EAR, EAT, EER, EST, HES, HIT, HOP, HOR, HORS, HORSE, HUP, NAE, NOB, NOBUT, ONT, OOT, OPP, ORS, OUR, OUT, PAR, PART, PAT, PEA, PEAT, PEE, PEER, PIR, POH, PUT, QAT, QUI, QUIT, QUITE, RAP, REE, RIP, RIPA, RTI, RUT, SEA, SEAR, STD, STR, STRA, STRAE, SUU, TAA, TAE, TAP, TAPIR, TEE, TIU, TOO, TRA, TRAP, TRI, TRIP, TUB, TUP, TUR, UDI, UIT, URE, UTE]
Rules

No exploiting standard loopholes
This is code-golf, so shortest code wins
Input and output may be in any convenient format
You may assume that both the grid and the words list will use only capital letters
The output order of the words does not matter
You do not have to, but may, filter out duplicates

Related.

@Lynn Even though I can think of one other approach, I agree, it too reduces to WSP.

Where were all of you when this was in the sandbox? Just saying. It got 3 upvotes there.

This is clearly not a duplicate. Although being on a torus doesn't sound like much of a change, most implementations will be significantly different. Here's my Python 3 approach anyway lambda s,d:[w for w in d if any(r(s,w,x,y,i,j)for x in range(l(s[0]))for y in range(l(s))for i in[-1,0,1]for j in[-1,0,1]if i*i+j*j)];r=lambda s,w,x,y,i,j:w==""or s[y%l(s)][x%l(s[0])]==w[0]and r(s,w[1:],x+i,y+j,i,j);l=len

Jelly, 25 bytes
Lẋ@Zɗ⁺ZU$3Ð¡;ŒD$€Ẏw€⁸ẸðÐf

A dyadic link accepting a list of lists of characters (the words) on the left and a list of lists of characters (the rows of the grid) on the right which returns a list of list of characters (the found words).
Try it online!
How?
Filters the words by their existence in the grid tiled to be word-length times as wide and word-length times as high:
Lẋ@Zɗ⁺ZU$3Ð¡;ŒD$€Ẏw€⁸ẸðÐf - Link: words, grid
                       Ðf - filter (the words) keeping those for which
                      ð   - ...the dyadic link to the left ...is truthy:
     ⁺                    -   perform this twice:
    ɗ                     -     last three links as a dyad:
L                         -       length (of the current word)
 ẋ@                       -       repeat (the rows) by (that number)
   Z                      -       transpose (making the rows become the columns)
         3Ð¡              -   repeat three times and collect the results (inc input):
        $                 -     last two links as a monad:
      Z                   -       transpose
       U                  -       upend     (together these rotate by a quarter)
                €         -   for €ach:
               $          -     last two links as a monad:
             ŒD           -       get forward-diagonals
            ;             -       concatenate
                 Ẏ        -   tighten (to get all the runs across the grid)
                    ⁸     -   chain's left argument (the word)
                   €      -   for €ach run:
                  w       -     sublist-index (0 if not found)
                     Ẹ    -   any truthy? (i.e. was the word found?)

JavaScript (Node.js), 269 214 164 163  bytes
-50 bytes with the golfing I learned since last year.
-1 byte thanks to Redwolf Programs
l=>g=>l.filter(w=>g.some((r,y)=>r.some((c,x,r,z=[-1,0,1],m=(a,b,c=b.length)=>(a%c+c)%c)=>z.some(l=>z.some(p=>[...w].every((h,i)=>h==g[m(l*i+y,g)][m(p*i+x,r)]))))))

Try it online!
old 214 bytes version:

(l,g)=>l.filter(w=>g.some((r,y)=>r.some((c,x,r,e=w.split``,m=(a,b)=>((a%b)+b)%b)=>[[0,1],[0,-1],[1,0],[-1,0],[1,1],[1,-1],[-1,1],[-1,-1]].some(v=>e.every((h,i)=>h==g[m(v[0]*i+y,g.length)][m(v[1]*i+x,r.length)])))))

Try it online!
Semi readable versoin:
(l, g) =>
    l.filter(w =>
        g.some((r, y) => //loop through rows
            r.some((c, x, r, e = w.split``, //loop through columns and split word in chars
                m = (a, b) => ((a % b) + b) % b) //modulo function which also works for negative
                =>
                [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]].some(v => //the different directions
                    e.every((h, i)
                        => h == g[m(v[0] * i + y, g.length)][m(v[1] * i + x, r.length)]
                    )
                )
            )
        )
    )

-1 byte: replace (l,g)=> with l=>g=>, and input is taken as (l)(g)

@RedwolfPrograms Thanks, I changed it. Not sure how to cut off more bytes

Clojure, 203 180 bytes
#(let[C count R range h(C %)w(C(% 0))](for[Q %2[y x][[1 0][0 1][-1 0][0 -1][1 1][1 -1][-1 -1][-1 1]]r(R h)c(R w):when(=(for[i(R(C Q))]((%(mod(+(* y i)r)h))(mod(+(* x i)c)w)))Q)]Q))

The grid must be a vector of vector of characters and the word list must be a sequence of sequence of characters. Sorry, no strings ;)

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Let's play Mölkky!
Mölkky
Mölkky is a Finnish throwing game. The players use a wooden pin (also called "mölkky") to try to knock over wooden pins of almost similar dimensions with the throwing pin, marked with numbers from 1 to 12. The initial position of the pins is as follows:
   (07)(09)(08)
 (05)(11)(12)(06)
   (03)(10)(04)
     (01)(02)

This description and the rules below are based on Wikipedia.
Simplified Mölkky rules

Knocking over one pin scores the number of points marked on the pin.

Knocking 2 or more pins scores the number of pins knocked over (e.g., knocking over 3 pins scores 3 points).

The aim of the game is to reach exactly 50 points. Scoring more than 50 is penalized by setting the score back to 25 points.

For the purpose of this challenge, we will make the assumption that the pins are always in the exact order described above. (In a real game, the pins are stood up again after each throw in the location where they landed.)

All other Mölkky rules are ignored and only a single player is considered.
Input
A non-empty list of lists of 12 booleans. Each list of booleans describes the outcome of a throw: 1 if the pin was knocked over and 0 otherwise. The booleans are given in the exact order of the pins, from top left to bottom right: 7, 9, 8, 5, 11, 12, 6, 3, 10, 4, 1, 2.
Output
The score after all throws described in the input, calculated by applying rules 1, 2 and 3.
Detailed example
Let's consider the following input:
// 07 09 08 05 11 12 06 03 10 04 01 02
[ [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],  // scores 5 (rule #1)
  [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],  // scores 2 (rule #2), total: 7
  [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 ],  // scores 7, total: 14
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],  // scores 12, total: 26
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],  // scores 12, total: 38
  [ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],  // scores 11, total: 49
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],  // scores 7, total: 56 -> 25 (rule #3)
  [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ] // scores 2, total: 27

The expected output is 27.
Challenge rules

You may take input in any reasonable format. Instead of lists of booleans, you can use integers where the most significant bit is the pin #7 and the least significant bit is the pin #2. In this format, the above example would be passed as [ 256, 2304, 127, 64, 64, 128, 2048, 3072 ].
The input list may contain throws where no pin at all is knocked over, in which case the score is let unchanged.
You don't have anything special to do when the score reaches exactly 50 points. But you can assume that no other throw will follow when it happens.
This is code-golf, so the shortest answer in bytes wins.

Test cases
Using lists of integers as input:
[ 0 ] --> 0
[ 528 ] --> 2
[ 4095 ] --> 12
[ 64, 0, 3208 ] --> 16
[ 16, 1907, 2048 ] --> 18
[ 2023, 2010, 1, 8 ] --> 29
[ 1726, 128, 35, 3136, 1024 ] --> 34
[ 32, 32, 2924, 2, 256, 16 ] --> 28
[ 64, 64, 2434, 1904, 3251, 32, 256 ] --> 25
[ 3659, 2777, 2211, 3957, 64, 2208, 492, 2815 ] --> 25
[ 2047, 1402, 2, 2599, 4, 1024, 2048, 3266 ] --> 50
[ 256, 2304, 127, 64, 64, 128, 2048, 3072 ] --> 27
[ 16, 8, 128, 1, 2048, 1, 2048, 513, 8, 3206 ] --> 30

You can follow this link to get these test cases in Boolean format.

Cool challenge, and also a great game to play in the summer for those of you who haven't tried it out — works great along with a grill.

@Nit Thank you. :) I have to confess that I didn't know this game until today. I saw people playing it while walking in a park this afternoon. Now, I'd like to give it a try.

Python 2, 126 111 108 104 bytes
-3 bytes thanks to Jonathan Allan
-4 bytes thanks to Kaya!
f=lambda A,t=0:t>50and f(A,25)or A and f(A[1:],t-~(sum(A[0])-1or 762447093078/12**A[0].index(1)%12))or t

Try it online!
Defines a recursive function that takes a 2D array of 1s and 0s and returns an integer value. Nothing too special in the construction, and I'm sure there's a simpler solution.
Explanation:
f=lambda A,t=0:    #Define the function, initialising t to 0 on the first iteration
               t>50and f(A,25)      #If t>50 then iterate again with t=25
                              or    #Else
               A and                #If A exists
                     f(A[1:],       #Iterate again without the first list of A
                        t-~         #And add to t, either
                           (sum(A[0])-1   #The sum of all elements if that's not 1
                                         or
                           762447093078/12**A[0].index(1)%12   #Else the appropriate pin value (black magic!)
               or t       #Finally, if A is finished, just return t

(0x103925BA4786>>4*A[0].index(1))%16 saves 1 character versus ord('GIHEKLFCJDAB'[A[0].index(1)])-65

A little more optimal: 762447093078/12**A[0].index(1)%12

That stuff looks like black magic to me! Thanks @Kaya!

That's just encoding with base 12

Jelly, 25 bytes
“ñ€bḷ’œ?TLḢṖ?µ€+25¹>?50ɗ/

A monadic link accepting a list of lists of ones and zeros (each of length 12) which returns an integer.
Try it online! Or see the test-suite (using the integer values given in the OP)
How?
This solution makes use of, œ?, which given a number, n, and a list finds the nth lexicographical permutation of the list where the list defines the sort order. First we need to work out this n:
 index:  1  2  3  4  5  6  7  8  9 10 11 12
 value:  7  9  8  5 11 12  6  3 10  4  1  2   (as defined by the question)
     P: 11 12  8 10  4  7  1  3  2  9  5  6   (our permutation lookup array)

...that is, P at index i is set to the original index of the value i.
This P has a lexicographical index of 438,337,469 (that is, if you took all 12! permutations of the numbers 1 to 12 and sorted them lexicographically, the 438,337,469th would be P).
This may be found using Jelly's Œ¿ atom.
Both steps may be performed in one go using the Jelly program ĠŒ¿
“ñ€bḷ’œ?TLḢṖ?µ€+25¹>?50ɗ/ - Link: list of lists of zeros and ones
             µ€           - perform the monadic chain to the left for €ach list:
“ñ€bḷ’                    -   base 250 number = 438337469
      œ?                  -   nth permutation (reorder the 1s and 0s to their pin values)
        T                 -   truthy indices (get the pin values of the 1s)
            ?             -   if...
           Ṗ              -   ...condition: pop (length greater than 1 ?)
         L                -   ...then: length (the number of pins)
          Ḣ               -   ...else: head (the first (& only) pin value)
                        / - reduce the resulting list of integers with:
                       ɗ  -   last three links as a dyad:
               +          -     addition (add the two values together)
                     50   -     literal fifty
                    ?     -     if...
                   >      -     ...condition: greater than (sum greater than 50 ?)
                25        -     ...then: literal twenty-five
                  ¹       -     ...else: identity (do nothing - just yield the sum)

I think your explanation about finding the appropriate lexicographical index among all permutations would be worth adding as a Jelly tip. (Last time I had to do that, I did a manual dichotomic search, which is not that long for short sequences but ... kinda tedious. ^^)

LOL; I had exactly the same solution, except for two different bytes: Ṗ -> Ḋ, µ -> Ʋ. Jelly would really benefit from acceppting a niladic link as ¡'s <link> (first argument), except that, if on the very start of the program, keep the special-casing behavior.

...and I almost used both!

Python 2, 90 bytes
Heavily inspired by Jo King's Python 2 answer and utilising Kaya's base-12 representation comment
t=0
for v in input():t+=sum(v)-1or 762447093078/12**v.index(1)%12;t=[t+1,25][t>49]
print t

Try it online! Or see the test-suite

Pyth, 51 48 38 bytes
VQI>=+Z?qJsN1@.PC"îO&"S12xN1J50=Z25;Z

Saved 10 bytes thanks to Jonathan Allan
Takes input as a list of lists of booleans.
Try it here
Explanation
VQI>=+Z?qJsN1@.PC"îO&"S12xN1J50=Z25;Z
VQ                                  ;     For each input...
    =+Z                                   ... add to the total...
       ?q sN1                             ... if one pin is down...
             @.PC"îO&"S12xN1              ... the score of that pin.
         J                    J           ... otherwise, the count.
  I>                           50         If we pass 50...
                                 =Z25     ... reset to 25.
                                     Z    Output the total.

Not sure how to get it into the program exactly, but it should save 6 or 7 bytes if you can... 7tT8h4hT12h5h2T4h02 -> .PC"îO&"S12 - uses lexicographical permutation indexing like my Jelly answer. (The code has an unprintable byte of 0x0F at the start of the string.)

)) can be ;

Perl 5, 74 70 bytes
$\+=y/1//-1||/1/g&&(0,6,8,7,4,10,11,5,2,9,3,0,1)[pos];$\=25if++$\>50}{

Try it online!
Takes input as a series of newline separated bitstrings.

05AB1E, 29 28 bytes
v•CÞŸαLć•13вyOΘmyÏOO25‚¬50›è

Try it online!
Explanation
v                              # for each boolean list in input
 •CÞŸαLć•                      # push 13875514324986
         13в                   # convert to a list of base-13 numbers
            yO                 # push the sum of y
              Θm               # truthify and raise the pin-list to this number (0 or 1)
                yÏ             # keep those which are true in the current list
                  OO           # sum the list and the stack
                    25‚        # pair with 25
                       ¬50›    # check if the first number is larger than 50
                           è   # index into the pair with this result

Java 10, 131 130 129 bytes
m->{int r=0,i,s,t;for(var a:m){for(i=s=t=0;i<12;s+=a[i++])t=a[i]>0?"    \n".charAt(i):t;r+=s<2?t:s;r=r>50?25:r;}return r;}

Contains 10 unprintables.
Input as integer-matrix of zeros and ones.
-1 byte thanks to @JonathanFrech, changing \t into an actual tab (works in TIO, doesn't work in my local IDE).
Try it online.
Explanation:
m->{                // Method with integer-matrix parameter and integer return-type
  int r=0,          //  Result-integer, starting at 0
      i,s,t;        //  Temp integers
  for(var a:m){     //  Loop over the integer-arrays of the input
    for(i=s=t=0;    //   Reset `i`, `s` and `t` to 0
        i<12;       //   Loop `i` in the range [0,12)
        s+=a[i++])  //    Increase `s` by the current value (0 or 1)
      t=a[i]>0?     //    If the current value is 1:
         "  \n".charAt(i)
                    //     Set `t` to the score at this position
        :t;         //    Else: Leave `t` the same
    r+=s<2?         //   If only a single pin was hit:
        t           //    Add its score `t` to the result
       :            //   Else:
        s;          //    Add the amount of pins `s` to the result
    r=r>50?         //   If the result is now above 50
       25           //    Penalize it back to 25
      :r;}          //   If not, it stays the same
  return r;}        //  Return the result

I think you can save one byte by using an actual tab character in "\t\n".

@JonathanFrech Hmm, indeed seems to work in TIO. Doesn't work locally in my IDE, but who cares about that I guess.. ;)

When there is a working implementation somewhere, it is allowed. :@

Haskell, 96 bytes
foldl(\s a->([s..50]++e)!!sum(last$zipWith(*)[7,9,8,5,11,12,6,3,10,4,1,2]a:[a|sum a>1]))0
e=25:e

Try it online!
The wrapping is clever: I essentially index at position s+sum(…) into the list ([0..50]++cycle[25]). However, a shorter way to write that is indexing at position sum(…) and beginning the list at s.

Charcoal, 43 bytes
≔⁰ηＦθ«≧⁺⎇⊖ΣιΣι⌕α§”$｜#z⁸Ｕg⊗”⌕ι¹η¿›η⁵⁰≔²⁵η»Ｉη

Try it online! Link is to verbose version of code. Takes input as a boolean array. Explanation:
≔⁰η

Set the score to 0.
Ｆθ«

Loop over the throws.
⎇⊖Σι

Is the number of pins 1?
Σι

If not, then take the number of pins.
⌕α§”$｜#z⁸Ｕg⊗”⌕ι¹

Otherwise, translate the position of the pin to a value.
≧⁺...η

Add it to the score.
¿›η⁵⁰≔²⁵η

If the score exceeds 50 then set it back to 25.
»Ｉη

Print the final result after all the throws.

Husk, 47 35 bytes
-12 bytes thanks to H.PWiz (better way of generating the list encoding points)!
F₅0
S?25>50+?←Lε`f`+Nm+3d4652893071

Try it online!
Explanation
F₅0  -- input is a list of boolean lists
F    -- left fold by
 ₅   -- | the function flipped (overflowing label) on line 1
  0  -- | with initial value 0

S?25>50+?←Lε`f`+Nm+3d4652893071  -- example inputs: [0,0,0,1,0,0,0,0,0,0,0,0] 0
                     4652893071  -- integer literal: 4652893071
                    d            -- digits: [4,6,5,2,8,9,3,0,7,1]
                 m+3             -- map (+3): [7,9,8,5,11,12,6,3,10,4]
              `+N                -- append natural numbers: [7,9,8,5,11,12,6,3,10,4,1,2,3,...
            `f                   -- filter this list by argument: [5]
        ?  ε                     -- if it's of length 1
         ←                       -- | take first
          L                      -- | else the length
                                 -- : 5
       +                         -- add to argument: 5
 ?  >50                          -- if the value is > 50
  25                             -- | then 25
S                                -- | else the value
                                 -- : 5

How about m+3d4652893071?

Haskell, 110 bytes
m s|sum s==1=sum$zipWith(*)[7,9,8,5,11,12,6,3,10,4,1,2]s|1>0=sum s
f l=foldl(\b->c.(b+).m)0l
c a|a>50=25|1>0=a

Same length: f l=foldl(\b a->last$b+m a:[25|b+m a>50])0l instead of f and c
Try it online!

Drop the l argument in f for 3 bytes.
f=foldl(\b->c.(b+).m)0

JavaScript (ES6), 98 bytes
a=>a.map(b=>b.map((m,i)=>(c+=m,d+=m*('0x'+'7985bc63a412'[i])),c=d=0)|(t+=c>1?c:d)>50?t=25:0,t=0)|t

Test cases:

f=
a=>a.map(b=>b.map((m,i)=>(c+=m,d+=m*('0x'+'7985bc63a412'[i])),c=d=0)|(t+=c>1?c:d)>50?t=25:0,t=0)|t

console.log(f([ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ])) // 0

console.log(f([ [ 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 ] ])) // 2

console.log(f([ [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] ])) // 12

console.log(f(
[ [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ] ]
)); // 16

console.log(f(
[ [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
  [ 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1 ],
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
])); // 18

console.log(f(
[ [ 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 ],
  [ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ] ]
)); // 29

console.log(f(
[ [ 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0 ],
  [ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1 ],
  [ 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],
  [ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ]
))  // 34

console.log(f(
[ [ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ],
  [ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 ],
  [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ] ]
))  // 28

console.log(f(
[ [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],
  [ 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0 ],
  [ 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0 ],
  [ 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1 ],
  [ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ] ]
))  // 25

console.log(f(
[ [ 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 ],
  [ 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1 ],
  [ 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1 ],
  [ 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1 ],
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],
  [ 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0 ],
  [ 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 ] ]
)) // 25

console.log(f(
[ [ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
  [ 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 ],
  [ 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ],
  [ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0 ] ]
)) // 50

console.log(f(
[ [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 ],
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ]
)) // 27

console.log(f(
[ [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
  [ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
  [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],
  [ 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0 ] ]
)) // 30

Same size as (and very similar to) my reference implementation. :)

Ah, cool.  I'm happy whenever I can match your code size.  It's only once in a blue moon that I can beat it :)

Red, 189 172 bytes
func[b][s: 0 foreach c b[d: 0 foreach e c[if e = 1[d: d + 1]]i: find c 1
n: either i[pick[7 9 8 5 11 12 6 3 10 4 1 2]index? i][0]if 50 < s: s + either 1 < d[d][n][s: 25]]s]

Try it online!
Explanation of the ungolfed code:
f: func[b][                                            ; a block of blocks of booleans
    s: 0                                               ; sets sum to 0
    foreach c b[                                       ; for each row of booleans
        d: 0 foreach e c[if e = 1[d: d + 1]            ; count the number of 1s
        i: find c 1                                    ; the index of the first 1
        n: either i[pick [7 9 8 5 11 12 6 3 10 4 1 2]  ; if there is 1, pick the number
                    index? i][0]                       ; at the index of 1
                                                       ; otherwise 0
        if 50 < s: s + either 1 < d[d][n][s: 25]       ; if there is only one 1, add
                                                       ; the number to the sum, otherwise
                                                       ; the number of 1s
                                                       ; if the sum > 50, reset it to 25
    ]
    s                                                  ; return the sum
]

Python 2, 109 105 103 bytes
c=0
for l in input():a=sum(l);c+=int('7985bc63a412'[l.index(1)],16)if a==1else a;c=(25,c)[c<51]
print c

Try it online!
Alternative without a recursive function.
-2 with thanks to @Jo King

Stax, 37 bytes
├T<↓"♥←~;▌6»≥øF←î5░U╚_π○Q▒<│∟└ù║pε♀▀æ

Run and debug it
Try It online!
Explanation
F:1"=EA5MQ9-I1%)"!s@c%1={h+}{%+}?c50>{d25}{}?    # Full program, unpacked

F                                                # Loop through every element
 :1                                              # Get indices of truthy elements
   "=EA5MQ9-I1%)"!                               # Push encoded [7,9,8,5,11,12,6,3,10,4,1,2]
                 s@                              # Swap the top 2 elements of stack and get elements at indexes
                   c%1=                          # Copy the top element, get length of array, compare to length of 1
                       {h+}{%+}?                 # If it has length of 1, add the element, otherwise add the length of the array to total
                                 c50>            # Compare total to 50,
                                     {d25}{}?    # If it is greater, pop it off and push 25 to reset counter, otherwise do nothing

Not my best work, but it works. I'm sure there is somehting I'm missing to make it a bit shorter.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Produce a m*n table in HTML
Input :
Two decimal integers m and n that respectively give the number of rows and columns of the table.
m and n are greater than or equal to 1.
Output :
A table in HTML that has m rows and n columns.
The table should be displayable by a modern browser of your choice. Most browsers will display everything properly even if tags are not closed. Proper indentation and spacing is optional.
There should be at least one (non-whitespace) printable character in each cell.
Cells on the first line should use  tags while the ones on the following lines should use tags.
Win condition :
This is code-golf so the shortest source-code for each language wins.
Input example :
2 3

Output example :

   A
   A
   A

   A
   A
   A

or :

AAA
AAA

Comments are not for extended discussion; this conversation has been moved to chat.

APL (Dyalog Unicode) with MiServer 3.0, 31 30 bytesSBCS
Full program. Prompts stdin for the two-element list [m,n] and prints strict XHTML to stdout.
(⎕NEW _.Table((⎕⍴0)⍬1)).Render

Example session:
      )xload C:\Users\Adam.DYALOG\Documents\MiServer\miserver.dws
C:\Users\Adam.DYALOG\Documents\MiServer\miserver.dws saved Wed Mar  7 17:19:40 2018
      Load ''
Development environment loaded
MiSite "C:/Users/Adam.DYALOG/Documents/MiServer/MS3/" loaded
      (⎕NEW _.Table((⎕⍴0)⍬1)).Render
⎕:
      2 3

0	0	0

0	0	0

Try it online!
Explanation:
(…).Render Render the following HTML element:
 ⎕NEW _.Table (…) a new Table with the following parameters:
  (…) ⍬ 1 the following content, no special styling, 1 header row:
   ⎕⍴0 evaluated input reshapes zero (i.e. an m-row, n-column matrix of zeros)

JavaScript (ES6), 70 bytes
Saved 2 bytes thanks to @RickHitchcock
Takes input in currying syntax (m)(n).
m=>n=>'
'+(g=c=>'
'+`<t${c}>A`.repeat(n))`h`+g`d`.repeat(m-1)

Try it online!
Demo

f=

m=>n=>'
'+(g=c=>'
'+`<t${c}>A`.repeat(n))`h`+g`d`.repeat(m-1)

O.innerHTML = f(2)(3)

Canvas, 31 bytes
<ŗ>
table⁸ｏ╶［tr⁸⁶｛¹１≡╵dh＠t×⁸；｝］

Try it here! or
Try it visualized!
After fixing 2 bugs (ಠ_ಠ) in the interpreter, 30 bytes works too

Python 2, 57 bytes
lambda m,n:'

'+'A'*n+('
'+'A'*n)*~-m

Try it online! Assumes m isn't zero.

05AB1E, 30 bytes
’<…È>’sF"
"„hdNĀè"<tÿ>A"I×J

Try it online!
Explanation
’<…È>’                           # push "
"
      sF                         # no-of-rows times do:
        "
"                   # push "
"
              „hd                # push "hd"
                 NĀ              # push the iteration counter truthified
                   è             # index into the 2-char string with this
                    "<tÿ>A"      # insert the result into the string "<tÿ>A" instead of ÿ
                           I×    # repeat this string no-of-columns times
                             J   # join the stack to a single string

JavaScript, 65 bytes

f=(m,n)=>m?f(--m,n)+'
'+`<t${m?'d':'h'}>x`.repeat(n):'
'

document.write(f(4,3));

recursion. nice!

Java 10, 139 133 102 bytes
m->n->{var r="
";for(int j=0,i;j++<m;)for(r+="
",i=n;i-->0;r+=j<2?"A":"B");return r;}

Try it online.
Explanation:
n->m->{                  // Method with two integer parameters and String return-type
  var r="
";       //  Result-String, starting at "
"
  for(int j=0,i;j++<m;)  //  Loop `j` over the rows in the range [0, `m`)
    for(r+="
",       //   Append "
" to the result
        i=n;i-->0;       //   Inner loop `i` over the columns in the range [`n`, 0)
      r+=j<2?            //    If `j` is 1 (first iteration):
          "A"        //     Append "A" to the result
         :               //    Else:
          "B");      //     Append "B" to the result
  return r;}             //  Return the result

I think there's a little typo, you wrote "th" twice.

@potato Ah, you're right. The code itself and the TIO-link were correct, but my explanation had a typo. Should be fixed now, thanks.

(m,n)->{var l="
";for(;n-->0;)l+="A";var s="
"+l.replace('d','h');for(;--m>0;)s+=l;return s;} (106 bytes) I found this one interesting, but not worth it given your current score. You probably can golf a bit your answer using ideas here like the mutable m.

@OlivierGrégoire I initially had a modifiable m, but due to the / differences it wouldn't matter. I still need to check whether it's the first iteration of the outer loop, in which case I need both j and m, and I need to do the inner loop multiple times, in which case I need i and n. Instead of going upwards from 0 and checking j<2 I could go backwards and check i>m-2, but it would be +1 byte instead of -1. Your approach of using two separated loops with modifiable m and n is indeed interesting, though. :)

C (gcc), 107 99 98 97 bytes
i;f(x,y){char s[]="A";for(puts("

");x--;s[2]=96+puts("
"))for(i=y;i--;)puts(s);}

Try it online!
-8 bytes thanks to potato
-2 bytes thanks to ceilingcat
The s array has to be declared as an array not a pointer otherwise it won't be editable (we set the first h to a d). Most browsers don't even care if your closing tag is correct, so we just close all tags with </t>.

Still works fine if you remove the </t> that appears twice and -8 bytes.

You can shave 4 more bytes off if you move outputting the new row to the inner loop (also, it avoids an empty row): Try it online!

APL (Dyalog Unicode), 42 38 bytesSBCS
-4 thanks to ngn.
Full program. Prompts stdin for the two-element list [m,n] and prints unclosed tags to stdout.
'
',∊'
',⍤1{'d'}@3⍀⎕⍴⊂'A'

Try it online!
⊂'A' enclose this string to treat it as a whole
⎕⍴ prompt for dimensions and cyclically reshape the single cell to a matrix of that size
…⍀ cumulatively insert the following function between each vertical pair of cells:
 {'d'}@3 ignore upper cell; place d at 3rd position in bottom cell
'
',⍤1 prepend this string each row
∊ ϵnlist (flatten)
'
', prepend this string

'd'⎕R'h' -> 'h'@3

(⊂'
'), -> '
',⍤1 and ...@1 -> ...⍀

@ngn All done. Thanks. Relevant.

R, 73 bytes
function(n,m)cat("

","A"<m,c("
","A"<m)<n-1)
"<"=rep

Try it online!
Saved 7 bytes with a dirty hack - replace "rep" by "<".

Stax, 28 bytes
üÉ$♠═?S┼╪├8°‼←sí☼←T≡┴╜ô‼\↑0ⁿ

Run and debug it
Unpacked, ungolfed, and commented, it looks like this.
"
"P  print "table"
"A"*    "A" repeated specified number of times
,D          repeat the rest of the program specified number of times
  "
"p   print "
" with no newline
  Q         print top of stack without popping
  .hd|t     replace "h" with "d"

Run this one

PowerShell Core, 72 68 bytes
Function F($m,$n){'

'+'A'*$n+('
'+'A'*$n)*--$m}

Try it online!
Here are my test cases and expected outputs (C.f., TIO)

m=2; n=3

AAA
AAA
m=1; n=3

AAA
m=4; n=2

AA
AA
AA
AA
m=2; n=8

AAAAAAAA
AAAAAAAA

Thanks, @mazzy, for the -4 bytes!

Brackets are optional. Try Function F($m,$n){'

'+'A'*$n+('
'+'A'*$n)*--$m}.

Nibbles, 24 23.5 22 21.5 bytes
;~"able"::"<t"$">".`,_:@"r"^_:@?$"d" "h"

Attempt This Online!
Takes arguments in the order cols rows. Outputs something like this (for 8 5):

00000000

11111111

22222222

33333333

44444444

Explanation
;~     Define function f(str)
"able"  and call it with str = "able":
:       join
:        join
"<t"      "<t"
$         str
">"      ">"
.      Map
`,      0...
_        number of rows
:       join
@        f
"r"       "r"
^        repeat
_         number of columns
:         join
@          f
?           if
$            row index is positive
"d"          then "d"
"h"          else "h"
           row index

K, 58 bytes
K version is whatever is included in KDB+ 3.5 2017.11.30.
Port of the Python answer above.  Ends up being 1 byte longer due to having to enlist and flatten multiple times.
{,/"

",(y#,"A"),(x-1)#,("
",/y#,"A")}

C# (.NET Core), 130 bytes
m=>n=>{var r="
";for(int i=0;i++<m;)r+="
"+string.Concat(System.Linq.Enumerable.Repeat(i<2?"H":"D",n));return r;}

Try it online!

APL+WIN, 68 63 56 bytes
12 bytes in total saved thanks to Adám
Prompts for number of rows followed by number of columns and outputs non-closure option:
t←⊂'
'⋄'
't(n⍴⊂'A'),,t,((⎕-1),n←⎕)⍴⊂'A'

@Adám Too trigger happy I am afraid. Looks OK now?

Yes, but you don't need the ∊ or the trailing parens: t,,((⎕-1),n←⎕)⍴r or the first two commas.

@Adám Thanks. Its not my day must be the heat (28C)!

Merge h and r into the main expression: '
't(n⍴⊂'A')t,,((⎕-1),n←⎕)⍴⊂'A'

Something isn't right. You only insert one
 for the body. Each row needs a
.

@Adám Check your last suggested mod nowhere is t defined which I had as . My expression above yields:

Let us continue this discussion in chat.

Try it online!

Retina, 56 54 bytes
(.+) (.+)

$1*$(
$2*$(@
T`\d`\h`^.*?r.*?r

Try it online! Edit: Saved 2 bytes thanks to @CowsQuack. Explanation: The first stage uses Retina 1's string multiplication first to generate the appropriate number of cells, then to generate the appropriate number of rows. The second stage then changes the first row of tds into ths.

If you know the input is going to be split by spaces, then you should be able to use . instead of \d

Haskell, 109 107 103 bytes
n!i="<t"++n++'>':i++"</t"++n++">"
r#c="able"!("r"!([1..c]*>"h"!"H")++([2..r]*>("r"!([1..c]*>"d"!"A"))))

So many parentheses… Thanks to @nimi for two bytes (and a loss of genericity)!
Try it online!
Without end tags the straight implementation wins at 87 bytes (Try it online):
r?c="

"++([1..c]*>"H")++([2..r]*>("
"++([1..c]*>"A")))++"
"

Perl 5 -p, 65 54 bytes
-11 bytes thanks to @msh2108's reminder
/ /;$_="

"."A"x$'.('
'.'B'x$')x$`

Try it online!

Save yourself some bytes. Per an example in the challenge, you can drop the .'
'.

Carrot, 77 51 bytes
A^*$v
vl+(^h)*($^F- 1)A"h"S"d"h+(^l)v

(While working on this, I discovered a bug with h not working and fixed it)
Golfed some bytes by shortening the html as well as using "split, join" instead of "replace"
Try it online!, use the command-line option -d to see the AST (Note: this uses the new node interpreter, so the older version on the website cannot run this.)
This program takes the input 0-indexed and in reversed order, because of Carrot's weird nature, thus 3 2 printing a 3×4 table.
Run the program like so, ./carrot -f prog.carrot input.txt
Basically creates the header row, then the data rows on another cell of the garden (2D tape), and concatenates them together.

Carrot works on a 2D tape, called a garden. Each cell on the garden is made up of three stack modes, string, float, array. There is a value for each mode, called a "stack" (note: misnomer). These stacks begin empty. When a cell is at a particular mode, the following commands will affect the stack that corresponds to this mode, for example in float mode, the operations will affect the stack float. And of course, there are commands for switching between modes. The modes are important because each operator can be overloaded for each mode and each argument type.
In addition, there are two additional modes (these only affect the commands, not the stack directly), normal mode and caret mode. Normal mode works normally, where there are operators taking in arguments and affecting the stack directly. In caret mode, (almost) every character is interpreted literally as a string, and is later prepended/appended accordingly to the stack. Caret mode is started/ended with carets (append) or down-carets (prepend).
Carrot begins in a cell on the garden, in stack-string mode, and in caret mode.

Beginning in caret-mode, the string A is added to the initially empty stack-string. Then follows the * command that duplicates it $, the input, times. Then
 is prepended to the stack-string by the usage of the down-caret v. This creates the header row of the table.
To create the data rows, we duplicate the header to another cell. l moves the IP to the right empty cell, and + appends (^h) the string in the cell to the left (essentially copying it to the cell on the right). () starts a subshell, a new Carrot program with almost the same tape, and ^ exits out of caret-mode so that we can h get the string in the left cell. This is then * duplicated by ($^F- 1), the next input minus 1, times.
Still in the right cell, A sets the array of this cell to its stack- tring split by "h". S joins the stack array by "d" and sets the stack string to this value. A"h"S"d" really just replaces hs with ds to form the data rows. Now h we move to the left starting cell.
Now we append the stack string of the cell to the right to this cell using +(^l). All that's remaining is to add the
 tag, so we do this by v prepending it.

Charcoal, 33 bytes

×AηＦ⊖θ«
×Aη

Try it online!
Explanation

                         Print "

"
           ×Aη                  Print "A" * second input
                  Ｆ⊖θ«            For i in (implicit) range over first input

        Print("
")
                            ×Aη Print("A") * second input

Powershell, 63 bytes
$m,$n=$args;$t='h';'
';1..$m|%{'
'+"<t$t>A"*$n;$t='d'}

save it as new-mntable.ps1. Test script:
.\new-mntable.ps1 2 3
.\new-mntable.ps1 1 3
.\new-mntable.ps1 4 2
.\new-mntable.ps1 2 8

output (extra spaces are optional):

AAA

AAA

AAA

AA

AA

AA

AA

AAAAAAAA

AAAAAAAA

Powershell, 65 bytes, -replace
'
h'+'d'*--$args[0]-replace'h|d',('
'+'<t$0>A'*$args[1])

save it as new-mntable.ps1. Test script:
.\new-mntable.ps1 2 3
.\new-mntable.ps1 1 3
.\new-mntable.ps1 4 2
.\new-mntable.ps1 2 8

output:

AAA
AAA

AAA

AA
AA
AA
AA

AAAAAAAA
AAAAAAAA

How it work:

'
h'+'d'*--$args[0] - create a string like
hddd...
'h|d'- search h or d chars in the string for replacing
'
'+'<t$0>A'*$args[1] - replace each char with string like
<t$0>A<t$0>A...
where $0 is a captured group[0] - the char in the -replace.

Powershell, 65 bytes, scriptblock
$m,$n=$args;'
';&($r={'
'+"<t$args>A"*$n})h;(&$r d)*--$m

save it as new-mntable.ps1. Test script:
.\new-mntable.ps1 2 3
.\new-mntable.ps1 1 3
.\new-mntable.ps1 4 2
.\new-mntable.ps1 2 8

output:

AAA

AAA

AAA

AA

AA
AA
AA

AAAAAAAA

AAAAAAAA

Vyxal, 34 bytes
`<∨ø>`?(`<tr>`‛hdn1>i`<t%>A`$%⁰*Wṅ

Try it Online!
Port of Emigna's 05AB1E answer.
Explanation
`<∨ø>`         # Push "
"
      ?(       # Input number of times:
        `<tr>` #  Push "

‛hd            #  Push "hd"
   n1>         #  Is the loop variable
               #  greater than 1?
      i        #  Index into "hd"
       `<t%>A` #  Push "<t%>A"
$%             #  Replace "%" with
               #  either "h" or "d"
   ⁰*          #  Multiply this string
               #  by the second input
     Wṅ        #  Join the stack into a string
               #  Implicit output

Go, 130 123 bytes
func f(r,c int)(s string){for d,i:="A",0;i<r;i++{if i>0{d="A"}
s+="
"
for j:=0;j<c;j++{s+=d}}
return"
"+s}

Attempt This Online!

-7 bytes from removing unused variable, condensing string literals (@xigoi)

What's the point of the R variable? The code seems to work without it.

Also, you can save 2 bytes by putting the "A" directly into the literals.

J, 64 bytes
Another port of the Python answer:
4 :0
'

',(;y#<'A'),;(<:x)#<('
',(;y#<'A'))
)

Jelly,  33  32 bytes
“A”ẋ”h3¦s5ẋ€ṭ€“
”ṭ“¢ssɱU»

A full program taking rows, columns which prints the result.
Try it online!

hmm, also 32 using a table:
Ịị⁾hdṭ”t⁾<>j;ðþZṭ€“
”ṭ“¢ssɱU»

Dart, 45 63 bytes
Working solution:
(m,n){print('

'+'A'*n+('
'+'A'*n)*(m-1));}

Try it online here!
Lambda/anonymous function taking m and n as parameters, displays output to STDOUT.
Since tables with unclosed
,
, , and  tags still render in modern browsers (ex., Chrome), the output is valid.
Old (broken) solution:
My first attempt forgot to switch to  after the first row:
(m,n){print('

'+'A'*n+('
'+'A'*n)*(m-1));}

Thanks to @Lynn for pointing that out.

Pyth, 40 bytes
J"
"AQ"
"J*H"A"*tGJ*H"A

Try it online!

Google Sheets, 66 bytes
="

"&Rept("A",B1)&Rept("
"&Rept("A",B1),A1-1)

Input is in cell A1 and B1.
There's nothing fancy, really; it's just nested Rept functions.
It does assume m > n > 0 and that they're both integers.

Forth (gforth), 86 bytes
: f ."
" 0 do ."
" dup 0 do j if ." A" else ." A" then loop loop ;

Try it online!
Explanation
."
"         \ output

0 do                \ start loop from 0 to m-1
   ."
"         \ output

   dup 0 do         \ duplicate n and loop from 0 to n-1
      j if          \ if the outer loop index is true (not 0)
         ." A"  \ output A
      else          \ if outer loop index is false (0)
         ." A"  \ output A
      then          \ end if-else
   loop             \ end inner loop
loop                \ end outer loop

PHP, 161 Bytes
Try it online
Code
function f($m,$n){$t=["table>","th>","td>","tr>","</"];echo strtr("
<0<3".str_repeat("<1A41",$n)."43".str_repeat("<3".str_repeat("
<2A42",$n)."43",$m-1)."40",$t);}

Explanation
function f($m,$n){
  $t=["table>","th>","td>","tr>","</"];           //array representing the tags its created
  echo strtr("<0<3".str_repeat("<1A41",$n)."43"   //strtr it's called and uses
                                                  //the array to replace values
           .str_repeat("<3".                      //repeat the tags
                         str_repeat("<2A42",$n)   //repeat the tags again
                            ."43",$m-1)."40",$t);
   //its repeated m-1 times because head is counted as one row
  }

PHP, 193 Bytes
Full table structure forgot <tfooter>
,
..etc..
Try example of the function
function f($m,$n)   {$t=["table>","thead>","tbody>","th>","td>","tbody>","tr>"];
echo strtr(
      "<0<1".str_repeat("<3A</3",$n).
      "</1<2".str_repeat(
                  "<6".str_repeat("<4A</4",$n)
                       ."</6",$m-1)."</2</0",
  $t);
  }

Explanation
$t=["table>","thead>","tbody>","th>","td>","tbody>","tr>"];
An array with all the tags for the table it's builded and then with str_repeat a number refering to an index in the array is written, then to strtr the string plus the array is passed

Yabasic, 124 bytes
An anonymous function that takes input from as space delimited integers and outputs to the console.
?"
"
input""i,j
For c=1To i
?"
"
For r=1To j
If c=1?"H	"
If c>1?"D	"
Next
?"
"
Next
?"
"

Try it online!

This doesn't produce the  tags.

@potato - ahh, I hadn't seen that. It's corrected.

K (ngn/k), 51 bytes
{"
",/"
",//:y#'(,,"A"),1_x#,,"A"}

Try it online!

Japt -P, 34 33 bytes
Æ"
"+"<t{XÎgdih}>A"pVÃu`<ta½e>

Try it
-1 thanks to a clever trick by Shaggy
Æ             # the range [0, #cols) with each X mapped to:
  "
"+     #   "
" prepended to
  "<t{        #     "<t" prepended to
    XÎgdih    #       index into "dh" with the sign of X
  }>A"        #     append ">A"
  pV          #     repeated #rows times
Ã             # end map over range
u`<ta½e>      # prepend the compressed string "

You can save a byte with XÎgdih.


text:
Nim Multiplication
Background
If you do much code golfing, you're likely aware of the bitwise XOR operation.  Given two integers, it gives another integer with 1s in the bits where the two inputs differ. So, for example, 1010 XOR 0011 = 1001.
It turns out to be very useful in game theory, where it's better known as the "nim sum". If you have the sum of two games (that is, you're making moves in one game at a time), the value of the position is the nim sum of the values of the positions in each individual game.
But we can take this a step further. With nim addition and an appropriate definition of nim multiplication, we can form a field from the nonnegative integers. So the challenge is to golf nim multiplication.
Definition
Nim multiplication obeys the following rules:
The nim product of a Fermat 2-power n = (2^(2^k)) with any smaller number is the ordinary product.
The nim product of a Fermat 2-power n with itself is 3n/2.
Nim multiplication distributes over nim addition.
Nim multiplication is commutative and associative (as is nim addition).
The multiplicative identity is 1 (and the additive identity is 0).
Any nonnegative integer can be written as the nim sum of distinct powers of two, and any power of two can be written as the product of distinct Fermat numbers, so this is sufficient to define nim multiplication for all nonnegative integers.
Example
That was all pretty abstract, so let's work through an example. I'll use + to denote nim addition (XOR) and * for nim multiplication.
6 * 13
= (4 + 2) * (8 + 4 + 1)
= (4 + 2) * ((4 * 2) + 4 + 1)
= (4 * 4 * 2) + (4 * 2 * 2) + (4 * 4) + (4 * 2) + (4 * 1) + (2 * 1)
= (6 * 2) + (4 * 3) + 6 + 8 + 4 + 2
= ((4 + 2) * 2) + 12 + 6 + 8 + 4 + 2
= (4 * 2) + (2 * 2) + 12 + 6 + 8 + 4 + 2
= 8 + 3 + 12 + 6 + 8 + 4 + 2
= 15

Additional Test Cases
4, 4 -> 6
4, 3 -> 12
4, 7 -> 10
2, 4 -> 8
2, 3 -> 1
1, 42 -> 42

Challenge
Write a program or function which, given two nonnegative integers in any convenient form, computes their nim product.
This is code-golf, so shortest submission wins.

In case it's not clear to readers, this is different from XOR (carryless) multiplication, and so not a duplicate of that challenge.

Nim multiplication tables in OEIS: A051775, A051776, A051910, A051911.

Also note that there are no intuitive way to understand nimber multiplication (according to that post).

Fermat numbers are of the form 2^(2^k)+1, so what you're calling a Fermat number is actually one less.

@KellyLowder Yes, it's really a Fermat 2-power.

I think your definition is missing the fact that 1 is the multiplicative identity.

Nim, 120 bytes
proc f(a,b:int):int=
 var s={0..a*b}
 for i in 0..<a*b:s=s-{f(i%%a,i/%a)xor f(a,i/%a)xor f(i%%a,b)}
 for i in s:return i

Try it online!
OK, this might be crazy, but somebody had to do Nim multiplication in Nim...
This is standard algorithm from Wikipedia. The problem is that I don't know the language, so had to learn the basics on the fly. In particular, I was surprised that -= and min didn't work for sets, and the best way I managed to find for extracting the minimum was to use the iterator and return the first value. Hopefully, Nim experts will help me to improve this.

I was wondering when someone would try this.

Python 2, 85 bytes
f=lambda x,y:min(set(range(x*y+1))-{f(i%x,i/x)^f(x,i/x)^f(i%x,y)for i in range(x*y)})

Try it online!
Slow as heck. Computes mex({α′ β ⊕ α β′ ⊕ α' β′ : α′ < α, β′ < β}) recursively.

Jelly, 16 bytes
p’ß/;ß"^/ʋ€ṭ‘ḟ$Ṃ

Uses the recursive formula xy = mex({ay ⊕ xb ⊕ ab : a < x, b < y}) for nimber multiplication.
Try it online!
How it works
p’ß/;ß"^/ʋ€ṭ‘ḟ$Ṃ  Main link. Left argument: x. Right argument: y.

p                 Cartesian product; yield the array of all pairs [a, b] such that
                  0 < a ≤ x and 0 < b ≤ y.
 ’                Decrement, changing the conditions to 0 ≤ a < x and 0 ≤ b < y.
          ṭ       Tack; yield [y, x].
        ʋ€        Combine the four links to the left into a dyadic chain. Call it
                  with right argument [y, x] and each of the [a, b] as left one.
  ß/                  Reduce [a, b] by the main link, computing the product ab.
     ß"               Zip [a, b] with [y, x] using the main link, computing the
                      array of products [ay, xb].
    ;                 Concatenate, yielding [ab, ay, xb].
       ^/             Reduce by bitwise XOR, yielding ab ⊕ ay ⊕ xb.
                  All that's left is to compute the minimum excluded (mex) non-
                  negative integer.
             $    Combine the two links to the left into a monadic chain.
           ‘          Increment the XOR sums.
            ḟ         Filterfalse; remove all incremented sums that appear in the
                      original sums.
              Ṃ  Take the minimum if the resulting array is non-empty or yield 0.
                 If x = 0 or y = 0, the array of sums is empty and Ṃ yields 0.
                 If x > 0 and y > 0, since 0 is among the sums, this finds the
                 smallest non-sum n+1 such that n ≥ 0 is a sum.
                 In either case, Ṃ yields xy.

CGSuite, 52 39 22 bytes
(a,b)->a.NimProduct(b)

Didn't realize it has this builtin, and anonymous "procedures".
Original version, 36 bytes:
(a,b)->*a.ConwayProduct(*b).NimValue

Or 25 bytes if the input/output could be nimbers:
(a,b)->a.ConwayProduct(b)

Well, I hoped *a**b/a*b to work, but it doesn't.

Definitely the right tool for the job.

Pyth, 21 bytes
Mf-TsmmxxgkdgkHgGdGH0

Demonstration
Uses the minimum excluded element formulation of nim multiplication, as given here.
Two nested maps are used to iterate over all smaller values (mm ... GH), then the results are flattened (s). The clever part comes with f-T ... 0, where we iterate over integers upward from 0 to find the first one not contained in the set mentioned above. By doing it this way, we don't need to calculate an iteration upper bound, saving a few bytes.
In the end, the function g computes the nim product.

JavaScript (ES6), 142 128 bytes

f=(x,y,z=Math.log2,v=x&-x,t=z(x),u=z(y),s=t&u,r=s&-s)=>x<2|y<2?x*y:x>v?f(v,y)^f(x^v,y):y&y-1?f(y,x):r?f(f(x>>r,y>>r),3<<r-1):x*y

<input id=x><input id=y>

The first step is to split both x and y into an XOR of powers of 2, take their pairwise nim products, and then XOR the results (because nim product distributes over XOR). Once we have recursed to the case of x and y both powers of 2, we note that Fermat powers multiply with each other using ordinary arithmetic, so we can therefore factorise x and y into Fermat powers. If x and y don't share a Fermat power we can reverse the process and simply return x * y. However if they share a Fermat power, then we divide both x and y by that power, calculate the nim product, then take the nim product with the nim square of that Fermat power. Ungolfed:
function nimprod(x, y) {
    if (x < 2 || y < 2) return x * y;
    var v = x & -x;
    if (x > v) return nimprod(v, y) ^ nimprod(x ^ v, y); // nimprod distributes over ^
    if (y & (y - 1)) return nimprod(y, x); // x is a power of 2 but y is not
    var t = Math.log2(x);
    var u = Math.log2(y);
    var s = t & u;
    if (!s) return x * y; // x and y do not share a Fermat power
    var r = s & -s;
    return nimprod(nimprod(x >> r, y >> r), 3 << r - 1); // square the Fermat power
}

Wolfram Language (Mathematica), 81 bytes
x_±y_:=Min@Complement[Range[0,x*y],##&@@Array[BitXor[x±#2,#±y,±##]&,{x,y},0]]

Try it online!
Using the formula:
\$\alpha \beta = \operatorname{mex}(\{\,\alpha' \beta + \alpha \beta' + \alpha' \beta' : \alpha' < \alpha , \beta' < \beta \,\}).\$


text:
Blackjack Bust Calculator
Blackjack,  also known as twenty-one, is a comparing card game between yourself and a dealer, where each player in turn competes against the dealer, but players do not play against each other.
Play goes as follows, the dealer deals you a card. The dealer then deals them-self a card, face down. The dealer then deals you another card. Then finally, the dealer deals them-self a card, face-up.
Challenge
Your challenge is to write a program (or function) that when run (or called), outputs (or returns) the probability that the next card the dealer gives you will make you bust, which means the cumulative score of cards in your hand after the dealer gives you another card is over 21.
Input
The three visible cards in play. They are the two cards you have in your hand, and the one face card you can see in the dealers hand. This can be in whatever format you find suitable for your application.
There are 52 cards in a deck(4 of each of the cards below). The value of the cards are as follows:
Symbol(Case Insensitive)  Name     Value
2                         Two      2
3                         Three    3
4                         Four     4
5                         Five     5
6                         Six      6
7                         Seven    7
8                         Eight    8
9                         Nine     9
T                         Ten      10
J                         Jack     10
Q                         Queen    10
K                         King     10
A or 1                    Ace      1

In Blackjack, an ace can count as 1 or 11. In our challenge, only count it as a 1
Output
The probability, in a ratio or percentage format, that the next card we draw will make us bust.
You may output the percentage, the fraction, or just the numerator of the fraction.
Examples
In this example, the first two cards are in our hand, the third card is the dealers visible card
 Input          ->       Output

 A 2 Q          ->       0.00%  or  0/49 or 0
 A 2 3          ->       0.00%  or  0/49 or 0
 T T T          ->       91.84% or 45/49 or 91.84
 T J K          ->       91.84% or 45/49 or 45
 9 7 3          ->       61.22% or 30/49 ...
 9 7 Q          ->       59.18% or 29/49 ...

Rules
Standard loopholes are not allowed.
This is code-golf, so the shortest code in bytes for each language wins!

Are we allowed to take the ace as 1 and face cards as 10s, or would that be stretching the input format too far?

So, we can take face cards as 10?

@Mnemonic Taking the Ace as 1 is fine.

@Mnemonic @wastl The inputs are only one character, so I am going to have to say no. Take them as QJKT.

Can I take them as lowercase letters?

@Mnemonic Yes that is fine.

@Arnauld Thank you for the catch. I updated the ratios but not the probabilities. As for your output question yest that is fine. You do not have to add the /49 on each answer.

"T J K -> 91.84% or 45/49 or 45 or etc..." - so we may simply output the numerator? If so could you state it in the text?

@JonathanAllan Updated

Jelly,  26  24 bytes
O%48«⁵µ13R«⁵ẋ4œ-+ṖS$>21S

A monadic link accepting a list of characters (using either the lower-case option OR the upper-case option with 1 for A) which returns the numerator (the number of 49ths) in [0,49].
Try it online! Or see the test-suite
How?
Note that by using lower-case the minimum of 10 and the ordinals modulo by 48 gives the card values. The same holds for upper-case T, J, Q, K and 1 for an ace, as shown on the right (but an upper-case A does not work):
     card:   a   2   3   4   5   6   7   8   9   t   j   q   k   |   1   T   J   Q   K
  ordinal:  97  50  51  52  53  54  55  56  57 116 106 113 107   |  49  84  74  81  75
   mod 48:   1   2   3   4   5   6   7   8   9  20  10  17  11   |   1  36  26  33  27
min(_,10):   1   2   3   4   5   6   7   8   9  10  10  10  10   |   1  10  10  10  10

O%48«⁵µ13R«⁵ẋ4œ-+ṖS$>21S - Link: list of characters   e.g. "q3a"
O                        - ordinals (of the input list)    [113, 51, 97]
 %48                     - modulo by 48                    [17,3,1]
     ⁵                   - ten
    «                    - minimum                         [10,3,1]
      µ                  - start a new monadic chain
       13R               - range of 13                     [1,2,3,4,5,6,7,8,9,10,11,12,13]
           ⁵             - ten                             10
          «              - minimum                         [1,2,3,4,5,6,7,8,9,10,10,10,10]
            ẋ4           - repeat four times               [1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10]
              œ-         - multi-set difference            [1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10  ,2  ,4,5,6,7,8,9   ,10,10,10]
                   $     - last two links as a monad:
                 Ṗ       -   pop                           [10,3]
                  S      -   sum                           13
                +        - add (vectorises)                [14,15,16,17,18,19,20,21,22,23,23,23,23,14,15,16,17,18,19,20,21,22,23,23,23,23,14,15,16,17,18,19,20,21,22,23,23,23,23,15,17,18,19,20,21,22,23,23,23]
                    >21  - greater than 21?                [0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1]
                       S - sum                             19

temptation to flat-out steal the mod-48 technology intensifies

If I do end up making an answer using mod-48 I'm bountying you 200 for the epic observation.

JavaScript (ES6), 73 62 bytes
Takes input as an array of 3 characters with 1 for aces. Returns the integer X representing the probability X/49 to be busted.
a=>([b,c]=a.map(v=>v*4||40)).map(n=>b-=n+b>52,b+=c-32)|b>12&&b

Try it online!
Exhaustive test
The golfed formula is not very intuitive. So, the easiest way to prove its consistency is probably to just compare all possible outputs against the ones provided by a basic ungolfed implementation:
g = a => {
  deck = [...'123456789TJQK'.repeat(4)];
  a.forEach(card => deck.splice(deck.indexOf(card), 1));

  return deck.filter(card =>
    (+a[0] || 10) +
    (+a[1] || 10) +
    (+card || 10) > 21
  ).length;
}

Try it online!

What does .map(n=>b-=n+b>52,b+=c-32) do in general? I'm not too familiar with JS's .map and trying to understand what the comma does here.. Initially I though it's a shorter variant of .map(n=>{b-=n+b>52;b+=c-32}) or something.. I know a=>([b,c]=a.map(v=>v*4||40)) converts ['1','2','Q'] to [ 4, 8, 40 ], and then it loops over these three values, where b is the first value, and c is the second (if I understand correctly). But I'm a bit confused about .map(n=>b+=(n+b<53)-1,b+=c-32) (if the first b-= is changed to b+=) vs .map(n=>b+=(n+b<53)-33+c)..

Hmm, or is it indeed b = first value, c = second value in [4, 8, 40], and the b-=n+b>52 modifies c as well if it's the second iteration? In which case combining both b-= and b+= into a single b+= (or b-=) won't work because of that?

@KevinCruijssen b+=c-32 is an (unused) parameter of map() and is evaluated only once before the first iteration. n=>b-=n+b>52 is the callback function (the 1st parameter of map()) and is called on each iteration. Technically, map() does accept a 2nd parameter (called thisArg), but this is irrelevant here: we just want this piece of code to be executed before the loop begins.

@KevinCruijssen Here is some code showing what's going on.

Ah ok, now it all makes sense. Thanks!

Pyth, 35 bytes
Jm?}dGTsdQclf>T-21sPJ.-*4+ST*3]TJ49

Takes input as a list of characters (or as a string).
Try it here
Explanation
Jm?}dGTsdQclf>T-21sPJ.-*4+ST*3]TJ49
Jm?}dGTsdQ                            Convert each input to the appropriate number.
                     .-*4+ST*3]TJ     Remove each from the deck.
           lf>T-21sPJ                 Count how many remaining cards bust.
          c                      49   Get the probability.

Java 8, 109 bytes
a->{int r=3;for(;r-->0;a[r]=a[r]<59?a[r]*4-192:40);r=a[0]+a[1]-32;for(int v:a)r-=v+r>52?1:0;return r>12?r:0;}

Port of @Arnauld's JavaScript (ES6) answer.
Input as character-array with three values, Aces as '1'; output is the probability p in p/49.
Try it online.
Explanation:
a->{                   // Method with integer-array as parameter and integer return-type
  int r=3;for(;r-->0;  //  Loop over the array
    a[r]=a[r]<59?      //   If the current item is a digit:
          a[r]*4-192   //    Multiply it by 4
         :             //   Else:
          40);         //    Change it to 40
  r=a[0]+a[1]-32;      //  Set `r` to the first value, plus the second value, minus 32
  for(int v:a)         //  Loop over the now modified array again
    r-=v+r>52?         //   If the current value plus `r` is larger than 52
        1              //    Decrease the result-integer by 1
       :0;             //   Else: Leave the result-integer the same
  return r>12?         //  If the result-integer is larger than 12
          r            //   Return the result-integer
         :             //  Else:
          0;}          //   Return 0

05AB1E, 46 bytes
Y9ŸJ.•§®т•«Á4×©sð.;#S|UεX‚˜ε®sk>T‚W}O21›}DOsg/

Try it online!
This can be done better, working on it.

Perl 5, 115 bytes
map{//;$k{$_}=4-grep$' eq$_,@F}1..9,T,J,Q,K;map{s/\D/10/}@F;$_=grep{$F[0]+$F[1]+$_>21}map{(s/\D/10/r)x$k{$_}}keys%k

Try it online!

Python 2, 97 96 bytes
def f(s):C=[min(int(c,36),10)for c in s];D=C[0]+C[1];return(4*D-35+sum(v+D<22for v in C))*(D>11)

Try it online!
Takes a 3-character string as input, with '1' being used as Ace. Returns the numerator.

05AB1E, 23 22 21 bytes
AST:4-D¨OÐ4@*4*Š+T@O-

Try it online!
AST:                   # replace all letters in the input with 10
    4-                 # subtract 4 from each card value
      D                # duplicate
       ¨               # drop the last element
        O              # sum (hand value of the player - 8)
         Ð             # triplicate that
          4@*          # set to 0 if it's less than 4
             4*        # multiply by 4
               Š       # 3-way swap
                +      # add the player's hand value to each card value
                 T@O   # count how many are >= 10
                    -  # subtract


text:
Circular Limited Sums
Challenge
Let's imagine an N-tuple of integers between 0 and M inclusive, and let's call it F.
There are (M + 1) ** N possible Fs in total.
How many such Fs satisfy all of the following inequalities (index is one-based)?

F[n] + F[n+1] <= M for 1 <= n < N
F[N] + F[1] <= M

Write a program or function that takes two positive integers N and M and outputs the answer in any convenient form.
Test Cases
(N,M) => Answer

(1,1) => 1
(2,1) => 3
(3,1) => 4
(4,1) => 7

(1,2) => 2
(2,2) => 6
(3,2) => 11
(4,2) => 26

(10,3) => 39175
(10,4) => 286555
(10,5) => 1508401

(25,3) => 303734663372
(25,4) => 43953707972058
(25,5) => 2794276977562073

(100,3) => 8510938110502117856062697655362747468175263710
(100,4) => 3732347514675901732382391725971022481763004479674972370
(100,5) => 60964611448369808046336702581873778457326750953325742021695001

Explanation
M (max value of element) = 1

F[1] + F[1] <= 1; F = [0]
(1,1) => 1

F[1] + F[2] <= 1; F = [0,0], [0,1], [1,0]
(2,1) => 3

F = [0,0,0], [0,0,1], [0,1,0], [1,0,0]
(3,1) => 4

F = [0,0,0,0], [0,0,0,1], [0,0,1,0], [0,1,0,0], [0,1,0,1], [1,0,0,0], [1,0,1,0]
(4,1) => 7

---

M = 2

F[1] + F[1] <= 2; F = [0], [1]
(1,2) => 2

F = [0,0], [0,1], [0,2], [1,0], [1,1], [2,0]
(2,2) => 6

F = [0,0,0], [0,0,1], [0,0,2], [0,1,0], [0,1,1], [0,2,0], [1,0,0], [1,0,1],
[1,1,0], [1,1,1], [2,0,0]
(3,2) => 11

(4,2) => 26 (left as exercise for you)

Rules

This is a restricted-complexity challenge. The time complexity of your code should be polynomial in M and N (e.g. you can't generate all (M + 1) ** N tuples and then check for the condition). Please explain your approach in your submission.
Standard code-golf rules apply. The shortest answer in bytes wins.

Python with numpy, 59 bytes
lambda M,N:trace(mat(tri(M+1)[::-1])**N)
from numpy import*

Try it online!
Uses matrix multiplication to count paths. If float precision is an issue, the mat could specify mat(...,int).

Using mat(...,int) does not seem to work for the n=100 cases. The method is correct (using sympy to sum the powers of the roots of the characteristic polynomial does work, for example), but numpy goes wrong somewhere as the numbers increase (maybe it's the ** power operator?)

MATL, 13 12 bytes
Q:&>~PiY^Xds

Try it online! This is a direct translation of xnor's Python answer and my first MATL answer, so it's most likely not optimal. E.g. there is likely a shorter way to get an upper-left triangular matrix of ones than t&lYRP. Edit: And it turns out there is, namely :&>~P. Thanks to Luis Mendo for -1 byte!
               M is the first input and N the second
Q:             increment M and generate range from 1 to M+1
  &>           compare vector element wise with itself with greater-than function
               results in a upper-right triangular matrix
    ~          inverse to get lower-left triangular matrix
     P         flip rows to get upper-left triangular matrix
      i        input N
       Y^      take the matrix to the power of N
         Xds   compute the sum of the main diagonal

@LuisMendo Thanks! Though it's only one byte or is there something else which can be dropped?

No, that's it, I can't count :-D

Pyth, 27 bytes
.N?Ys:RTtYh-QNgQ+NTs:Rdtszh

Demonstration
Expects input in the format:
M
N

This is classic dynamic programming, over the left end of the values set so far, the right end, and the current size of the gap.
How it works, in pseudocode/Python:
.N          | define memoized fill(left, right, gap):
?           | if cap > 0 then
s:RTtY      | sum(fill(i, right, gap - 1)
h-QN        |     for i in range(M - left + 1))
gQ+NT       | else M >= left + right
            | output:
s:Rdtsz     | sum(fill(i, i, N - 1)
h           |     for i in range(M + 1))

Q is used for M, z is used for N, : is fill, N is left, T is right, Y is gap.

Stax, 17 bytes
°(√&╒íÆ½╨⌂'├╖▼1_Z

Run and debug it
Unpacked, ungolfed, and commented, it looks like this.
^1](    [1, 0, ... 0] with M zeroes
:)      get all rotations of the array
{       begin block
  {:+rm map each array to reverse(prefixSums(arr))
},v*    execute preceding block N-1 times
F       for each array, execute the rest of the program
  iT    remove the last i elements from the array, where i is the iteration index
  F+    add the remaining elements to the running total
        implicitly print output

Run this one

R, 72 bytes
function(M,N)sum(diag(Reduce(`%*%`,rep(list(outer(0:M,0:M,"+")<=M),N))))

Try it online!
Ports xnor's approach.
Fails for larger test cases as R only has 32-bit integer support (they get cast to double once the max int value is reached), so using gmp or another arbitrary precision arithmetic library would be required.
Strangely, R lacks a matrix power operator, as ^ always applies elementwise.

Actually, there is a properly implemented %^% operator in package expm that would allow for -5 bytes, but unfortunately, it is not available on TIO (I had to test locally).

@KirillL. yeah, I had considered that but I think I'll stick with my base R response. Also you can golf that down to 60 bytes by not loading in the whole package: function(M,N)sum(diag(expm::\%^%`(outer(0:M,0:M,"+")<=M,N)))`

APL (Dyalog Unicode), 31 25 bytes
+/1 1⍉+.×⍣(⎕-1)⍨⌽∘.≤⍨⍳1+⎕

Try it online!
A full program which takes N, then M as inputs.
Follows the same algorithm as xnor's Python solution.
-6 bytes from Bubbler.

{x+.×⍵}⍣(...) → x+.×⍣(...), then x+.×⍣(...)⊢x←... → +.×⍣(...)⍨ to get 25 bytes.

Should've spotted that. Thanks!