[Question]
  [
Given a list of words and a grid of letters, find all the words in the grid and remove any letters which are not part of any of the words. The words could be forwards, backwards, up, down or diagonal. You may assume that no word in the list will occur in more than one place in the grid.
Input will always be: a list of words, 1 per line, followed by a blank line, followed by the grid of letters.
## Examples
**Input**
```
ADA
ALGOL
ASSEMBLY
BASIC
COBOL
DELPHI
FORTRAN
JAVA
LABVIEW
LOGO
PASCAL
PERL
PHP
PYTHON
SMALLTALK
VISUALC
LLJKCABLFCI
OROLOBOCOIM
GELACSAPRSX
LPSTAHWVTAV
ANRLXLXQRBI
IHPLEDOXAHS
KJYAPHPYNOU
FABMADANZJA
EVISNOHTYPL
AAYLBMESSAC
WEIVBALOGOM
```
**Output**
```
LL K    FC
OR LOBOCOI 
GELACSAPRS
LP T    TAV
A  L    RBI
IHPLED  A S
 J APHP N U
 A MADA   A
 V SNOHTYPL
 AYLBMESSAC
WEIVBALOGO
```
**Input**
```
BACKSPACE
BOLD
CLOSE
COMPACTDISC
COPY
CPU
CURSOR
DELETE
DESKTOP
DVD
EDIT
ENTER
EXIT
FLOPPY
FONT
HARDWARE
INTERNET
KEYBOARD
MONITOR
MOUSE
PASSWORD
PASTE
RETURN
SAVE
SOFTWARE
START
TEXT
TOWER
WORDPROCESSING
IAUERAWTFOSICPN
DGZPFLOPPYARFLU
RSNOCURSORVZDBM
AMNIUOMRNHEGUIN
OTBNSRMONITORNT
BEYTTSGPJBOLDRT
YRQEAHEHARDWARE
EOGRRNECECLOSEP
KIONTYKTODTOWER
ELCENSUPERPDKNN
ATRTPRYKELPVIEJ
GIEANPOTKSEDUSL
NXCMPASSWORDRUC
TEDITAGVSWJCTOV
CWOYPGYQKNLVXMW
```
**Output**
```
  UERAWTFOS    
DG PFLOPPYA    
R NOCURSORV    
A NI O    E    
OT NS MONITOR  
B  TTS P BOLD  
Y  EA EHARDWARE
E  RRNECECLOSE
K  NT KTO TOWER
   E SUPER D   
 TRTPRY ELPVIE 
 IEANPOTKSED S 
 XC PASSWORDRUC
TEDITA       O 
    P        MW
```
This is code-golf - shortest solution wins.
Example wordsearches from [1](http://www.whenwewordsearch.com/word_search/computer_programing_languages/1899/word_search.jsp) and [2](http://www.wordsearchfun.com/51198_Computer_Terminology_wordsearch.html).
  
[Answer]
## Perl - 230 chars
Count includes 4 for "-ln " command-line options.
```
if(1../^$/){push@w,$_,''.reverse if$_}else{$a.="$_\n"}END{$_=$a;/.+/;$W=$+[0];y/A-Z/ /;chomp;for$w(@w){for$n(0,$W-1..$W+1){$r=join".{$n}",map"($_)",(@l=split//,$w);if($i=$a=~/$r/s){substr($_,$-[$i++],1,shift@l)while@l}}}print}
```
Ungolfed:
```
# -n: implicitly loop over input lines
# -l: strip the newlines
if ( 1 .. /^$/ ) {              # from first line to empty line
  push @w,                      # record in @w
    $_,                         #   the word
      ''.reverse                #   and its reverse
        if $_                   #   if it's not the empty line
}
else {
  $a .= "$_\n"                  # otherwise, add to the search array
}
END {
  $_ = $a;                      # make a copy for the output
  /.+/; $W = $+[0];             # compute array width
  y/A-Z/ /;                     # blank the output board
  chomp;                        # and remove the trailing newline,
                                #  because -l will add it back for us
  for $w (@w) {                 # for each word
    for $n (0, $W-1 .. $W+1) {  # for each direction in E, SW, S, SE
      $r = join ".{$n}",        # form a regexp with an appropriate
                                #  number of characters skipped between letters
                                #  (0 -> adjacent, so E; $W -> next line, so S;
                                #   off by one from $W for the diagonals),
        map "($_)",             #  capturing the letters of the word (for their offsets),
          (@l=split//,$w);      #  which we split up here
      if ( $i = $a =~ /$r/s ) { # if the word matches in this orientation
        substr( $_,             # set the substring of the output
                $-[$i++],       #  at the offset this letter matched
                1,              #  length 1
                shift @l )      #  to the corresponding letter
          while @l              #  (for each letter)
      }
    }
  }
  print                         # and print the output
}
```
[Answer]
## Ruby 1.9, 214 210 206 182 177 173 172 166
```
s,G=$<.read.split$/*2
O=G.tr'^
',' '
(s+$/+s.reverse).split.map{|w|[0,l=G=~/$/,l+1,l-1].map{|d|(k=G=~/#{[*w.chars].*?.*d}/m)&&w.size.times{|i|O[k+d*i+i]=w[i]}}}
$><<O
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 87 (or 83?) [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
||UŒµVX8FD¬ªY√•iY1:AuS√∞:1Y:}D‚Ç¨g¬©√ãiŒµS√ê0:¬´NF√Å}}√∏√≠J0Œ¥K√µK√´¬Æ√†¬©FD¬Æ¬£‚Ç¨–ΩJRsŒµN¬Æ‚Äπi¬¶}}¬¶}\)]‚Ç¨S√∏Œµ{Œ∏}J¬Æ√§¬ª
```
With the actual I/O as mentioned in the challenge description.
[Try it online.](https://tio.run/##PVBNixQxEL3XP/EwsHuTuaWT6p70R5JNJd2TRQ8riAyIe1g8qNugXr34EwQ/YFkdPDgwsnjpvjf@hv0jY82OekilqOK9eu@dX5w9Wj3e7S4v47Rpl/dzNdyk8fMqHc/Fcxq/z4/TvFe3b78@Ga7Gd6tpM76no/lwbfLxTU/9uB2/lUfTj2rcVOP1sB4/DFdMsR4@MuT3r9JfTBszrG9f/1wNX/qe34N7D3lF43bavJq2fcmYT8PNbpcJWZETEiGztQJZW0KQtuFRUJok9y6BdBFk9GQ9KKwxIH9UBetAtQpQ6QBoAnrAJbd5bR2DcmsCLIRXnfAIer83GKDClFmeQmONDszY2Mg3nSDqLI@5YX6PIXoDJFoEsnm446AgfICASy6243N7gPNWIpE2BYAWEb3oQm5JS2dAFafuoEb4vI7gydiDj/ZUZQ2IxuhoG28WWERtwIbMkP8rjNVnmEKgwpX7cPh08icoFvjfFNrCsymJd7k5qDR7ThyMOujDWqKh6NA7VRkDIvjgfKqwdq3GEgqNwjgbKkIVqQazlM2/IHyUbJWjFUVLXSmDbUF2NrkinVSmbpdNt5vNnp3Pnp69fPEH) (For some reason, the `√Å` is very slow on an inner list of characters instead of a string in this program, so `ŒµS√ê0:¬´NF√Å}}` has been replaced with `Œµ√êS0:¬´NF√Å}S}` (rotate first; then convert it to a list of characters) to speed things up substantially - it'll now output on TIO in roughly a second, instead of timing out without any output after 60 seconds.)
With less strict I/O (first words-input as a list, second grid-input as a list of lines; output-grid as a list of lines as well), this would be **83 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)** instead:
```
ŒµVI8FD¬ªY√•iY1:AuS√∞:1Y:}D‚Ç¨g¬©√ãiŒµS√ê0:¬´NF√Å}}√∏√≠J0Œ¥K√µK√´¬Æ√†¬©FD¬Æ¬£‚Ç¨–ΩJRsŒµN¬Æ‚Äπi¬¶}}¬¶}\)]‚Ç¨S√∏Œµ{Œ∏}J¬Æ√§
```
[Try it online](https://tio.run/##TVFNb9QwEL3zM3JDYqX2Vu3NsSdZ58Pjepxk07KHIiG0EqKHigOgSMCVCz8BiQ@pKqw4sNJWiEt8j/gN/SOL7bYSh2TezHie3zyfX5w9WT/d76dtK48yMf7u3dd1fzhnL8n9nB/280HcvP/@bLx0H9bT1n2kg/l4pTL3bqDB7dyP4mD6Vbpt6a7Gjfs0XnqKzfjZj/z9U5iLaavGzc3b6/X4bRj89/jhyrfI7abtm2k3FH7my35/mqSMl6QZh@RRkmIlfOAVUkg51r5hhSQeM92HoJvwbwyh8UBABRYioNKiDqgNJCCkDUFZCOdgGdOsQh1pMlQhXzAjOmYCgQwnFYRqCX2KvuNhjUraeFONTVSlGVGHselhvNuAbYzygFgbcsLM3rGSZSZQWljGgF2UEwi0QQ5EUuXJ6sFpIlkDhnU2Q5JcBzaRn@hbwcxkVVjbkMLb1dsTkda@wmolG6yNWkDeyDCFNlVk7nTHJVPoraVcF8HfqKY3x8AW8N/2gLnx23OI5gcbS@kt6r2n4l40VBwUNRqMFqUKdzFrrDZ9CZVuJRS@kktgSqMtCURDla@oJa/vPTMNj174t2F5S13BLbbhOTvsdd4fl6pql3WXrPaz2Yvz2fOz16/@AQ) (with the same modification as above so it won't time out).
**Explanation:**
In pseudo-code, I do the following steps:
```
Map over the list of words:
 Push the input-grid
 Loop 8 times:
  If the word is present horizontally left-to-right:
   Replace everything else with a space
  Rotate the grid 45 degrees counterclockwise
Reduce/combine all grids of spaces and words
```
As for the actual code, of which most (50 bytes) is used to rotate the grid 45 degrees:
```
|                      # Get all inputs until an empty line is encountered,
                       # resulting in the list of words
 |                     # Do it again, resulting in the grid
  U                    # Pop and store the grid in variable `X`
 Œµ                     # Map over each of the words:
  V                    #  Pop and store the word in variable `Y`
  X                    #  Push grid `X`
   8F                  #  Loop 8 times:
     D¬ªY√•              #   Check if the word is in the grid:
     D                 #    Duplicate the grid
      ¬ª                #    Join the lines with newline delimiter
       Y√•              #    Check that this contains the word `Y`
         i             #   If this is truthy:
          Y1:          #    Replace the word temporarily with a 1
          AuS√∞:        #    Replace all uppercase letters with a space
          1Y:          #    Replace the 1 back to the word
         }             #   Close the if-statement
     D‚Ç¨g¬©√ãiŒµS√ê0:¬´NF√Å}}√∏√≠J0Œ¥K√µK√´¬Æ√†¬©FD¬Æ¬£‚Ç¨–ΩJRsŒµN¬Æ‚Äπi¬¶}}¬¶}\)
                       #   Rotate the grid 45 degrees counterclockwise:
     D‚Ç¨g¬©√ã             #    Check if the grid is a rectangle:
     D                 #     Duplicate the grid
      ‚Ç¨g               #     Get the length of each row
        ¬©              #     Save this list of lengths in variable `¬Æ` (without popping)
         √ã             #     Check whether these lengths are all equal
          i            #    If this is truthy:
           Œµ           #     Map over each row:
            S          #      Convert it to a list of characters
             √ê0:¬´      #      Append the row-length amount of 0s to the row
             √ê         #       Triplicate the row
              0:       #       Pop two, and replace all characters to 0s
                ¬´      #       Merge this list of 0s to the row
             NF        #      Loop the 0-based map-index amount of times:
               √Å       #       Rotate the row once towards the right
             }         #      Close the loop
           }           #     Close the map
            √∏√≠         #     Now rotate 90 degrees clockwise:
            √∏          #      Zip/transpose; swapping rows/columns
             √≠         #      Reverse each row
              J        #     Join the inner list of characters back to a string
                Œ¥      #     Map over each row:
               0 K     #      Remove all 0s from the row
                  √µK   #     Remove any empty rows
          √´            #    Else (it's a diamond-shape instead):
           ¬Æ           #     Push the list of lengths
            √†          #     Pop and push its maximum
             ¬©         #     Store this maximum as new variable `¬Æ` (without popping)
              F        #     Loop this maximum amount of times:
               D       #      Duplicate the list
                ¬Æ¬£     #      Only leave the first max amount of values
                  ‚Ç¨–Ω   #      Only leave the first character of each row
                    J  #      Join these characters together to a string
                     R #      Reverse it
               s       #      Swap so the list is at the top again
                Œµ      #      Map over each row:
                 N¬Æ‚Äπi  #       If the map-index is smaller than max `¬Æ`:
                     ¬¶ #        Remove the first character
                    }  #       Close the if-statement
                }      #      Close the map
                 ¬¶     #      Remove the first (now empty) row
              }        #     Close the loop
               \       #     Discard the now empty list
                )      #     Wrap all rows on the stack into a list
 ]                     # Close the open if-statement; loop; and map
                       # (we now have a list space-grids, except for the found words)
  ‚Ç¨S                   # Convert each inner grid to a flattened list of characters
    √∏                  # Zip/transpose; swapping rows/columns
     Œµ                 # Map over each inner list:
      {                #  Sort; spaces at the front, potential letter(s) at the end
       Œ∏               #  Pop and leave the last character
     }                 # Close the map
      J                # Join everything together to one huge string
       ¬Æ               # Push the last maximum `¬Æ`
        √§              # Split the string into that many equal-sized parts
         ¬ª             # Join the list of rows with newline delimiter
                       # (after which it is output implicitly as result)
```
[Answer]
**JavaScript:** 342 characters 
[Code-Golfed version:](http://jsfiddle.net/briguy37/utaf6/)
```
function a(b){c='\n';d=b.split(c+c);e=d[1].split(c);for(f=-1,g=[];h=e[++f];)for(i=-1,g[f]=[];h[++i];)for(j=-2,g[f][i]=' ';2>++j;)for(l=-2;2>++l;)for(k=0;m=d[0].split(c)[k++];)for(n=-1;o=m[++n];)for(p=f-n*j-j,q=i-n*l-l,r=0;(s=m[r++])&&(t=e[p+=j])&&(u=t[q+=l])&&s==u;)if(r==m.length)g[f][i]=o;for(i=0;v=g[i];)g[i++]=v.join('');return g.join(c)}
```
[Formatted version:](http://jsfiddle.net/briguy37/78HGh/)
```
function solveWordsearch(input){
    var lineBreak = '\n';
    var solver = input.split(lineBreak+lineBreak);
    var board = solver[1].split(lineBreak);
    for(row=-1,output=[]; line=board[++row];){
        for(col=-1,output[row]=[]; line[++col];){
            for(rowIncrement=-2,output[row][col]=' ';2>++rowIncrement;){
                for(colIncrement=-2;2>++colIncrement;){
                    for(k=0; word=solver[0].split(lineBreak)[k++];){
                        for(charPosition=-1; wordChar=word[++charPosition];){
                            var startRowIndex=row-charPosition*rowIncrement-rowIncrement;
                            var startColIndex=col-charPosition*colIncrement-colIncrement;
                            for(wordIndex=0;(compareWordChar=word[wordIndex++])&&(compareBoardRow=board[startRowIndex+=rowIncrement])&&(compareBoardChar=compareBoardRow[startColIndex+=colIncrement])&&compareWordChar==compareBoardChar;){
                                if(wordIndex == word.length){
                                    output[row][col]=wordChar;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    for(i=0;outLine=output[i];){
        output[i++]=outLine.join('');
    }
    return output.join('\n');
}
```
The concept behind this solution is to iterate over all positions on the board, initialize a 2D-array's values to ' ' for each position, and then consider all potential word directions and word offsets. If a matching word is found, the array's value for that position is updated to the correct letter. Finally, the array is converted to a string and returned.
[Answer]
# [BQN](https://mlochbaum.github.io/BQN/), ~~126~~ 114 bytes[SBCS](https://github.com/mlochbaum/BQN/blob/master/commentary/sbcs.bqn)
```
{S‚Üê-++`√ó¬¨‚ãÑ{wùïäg:g‚äë‚àò‚ÜëÀú¬®¬Ø2+‚à®¬¥‚•äw{H‚Üê‚äíÀú‚àä¬∑‚•ä(‚Üï‚â†ùï®)+‚åú¬∑/ùï®‚ä∏‚ç∑‚ãÑ(HÀò‚à®1‚ÜìÀò‚äíÀú‚åΩ‚ÅºÀò¬∑HÀò‚åæ‚çâ‚äíÀú‚åΩÀò' '‚ä∏‚àæÀò)‚åæ(‚åΩ‚àò‚çâ‚çüùï©)g}‚åú‚Üï4}‚üú>¬¥(S‚ü®‚ü©‚ä∏‚â°¬®)‚ä∏‚äîùï©‚äîÀúSùï©='
'}
```
[Run online!](https://mlochbaum.github.io/BQN/try.html#code=RiDihpAge1PihpAtKytgw5fCrOKLhHt38J2Vimc6Z+KKkeKImOKGkcucwqjCrzIr4oiowrTipYp3e0jihpDiipLLnOKIisK34qWKKOKGleKJoPCdlagpK+KMnMK3L/Cdlajiirjijbfii4QoSMuY4oioMeKGk8uY4oqSy5zijL3igbzLmMK3SMuY4oy+4o2J4oqSy5zijL3LmCcgJ+KKuOKIvsuYKeKMvijijL3iiJjijYnijZ/wnZWpKWd94oyc4oaVNH3in5w+wrQoU+KfqOKfqeKKuOKJocKoKeKKuOKKlPCdlaniipTLnFPwnZWpPScKJ30KCkYgIkJBQ0tTUEFDRQpCT0xECkNMT1NFCkNPTVBBQ1RESVNDCkNPUFkKQ1BVCkNVUlNPUgpERUxFVEUKREVTS1RPUApEVkQKRURJVApFTlRFUgpFWElUCkZMT1BQWQpGT05UCkhBUkRXQVJFCklOVEVSTkVUCktFWUJPQVJECk1PTklUT1IKTU9VU0UKUEFTU1dPUkQKUEFTVEUKUkVUVVJOClNBVkUKU09GVFdBUkUKU1RBUlQKVEVYVApUT1dFUgpXT1JEUFJPQ0VTU0lORwoKSUFVRVJBV1RGT1NJQ1BOCkRHWlBGTE9QUFlBUkZMVQpSU05PQ1VSU09SVlpEQk0KQU1OSVVPTVJOSEVHVUlOCk9UQk5TUk1PTklUT1JOVApCRVlUVFNHUEpCT0xEUlQKWVJRRUFIRUhBUkRXQVJFCkVPR1JSTkVDRUNMT1NFUApLSU9OVFlLVE9EVE9XRVIKRUxDRU5TVVBFUlBES05OCkFUUlRQUllLRUxQVklFSgpHSUVBTlBPVEtTRURVU0wKTlhDTVBBU1NXT1JEUlVDClRFRElUQUdWU1dKQ1RPVgpDV09ZUEdZUUtOTFZYTVci)
One third of the code is parsing the input, the more interesting parts are outlined below:
```
{wùïäg:g‚äë‚àò‚ÜëÀú¬®¬Ø2+‚à®¬¥‚•äw{H‚Üê‚äíÀú‚àä¬∑‚•ä(‚Üï‚â†ùï®)+‚åú¬∑/ùï®‚ä∏‚ç∑‚ãÑ(HÀò‚à®1‚ÜìÀò‚äíÀú‚åΩ‚ÅºÀò¬∑HÀò‚åæ‚çâ‚äíÀú‚åΩÀò' '‚ä∏‚àæÀò)‚åæ(‚åΩ‚àò‚çâ‚çüùï©)g}‚åú‚Üï4}
```
[Run online!](https://mlochbaum.github.io/BQN/try.html#code=RiDihpAge3fwnZWKZzpn4oqR4oiY4oaRy5zCqMKvMiviiKjCtOKlind7SOKGkOKKksuc4oiKwrfipYoo4oaV4omg8J2VqCkr4oycwrcv8J2VqOKKuOKNt+KLhChIy5jiiKgx4oaTy5jiipLLnOKMveKBvMuYwrdIy5jijL7ijYniipLLnOKMvcuYJyAn4oq44oi+y5gp4oy+KOKMveKImOKNieKNn/CdlakpZ33ijJzihpU0fQoKdzEg4oaQICJBREEi4oC/IkFMR09MIuKAvyJBU1NFTUJMWSLigL8iQkFTSUMi4oC/IkNPQk9MIuKAvyJERUxQSEki4oC/IkZPUlRSQU4i4oC/IkpBVkEi4oC/IkxBQlZJRVci4oC/IkxPR08i4oC/IlBBU0NBTCLigL8iUEVSTCLigL8iUEhQIuKAvyJQWVRIT04i4oC/IlNNQUxMVEFMSyLigL8iVklTVUFMQyIKZzEg4oaQIDEx4oC/MTHipYoiTExKS0NBQkxGQ0lPUk9MT0JPQ09JTUdFTEFDU0FQUlNYTFBTVEFIV1ZUQVZBTlJMWExYUVJCSUlIUExFRE9YQUhTS0pZQVBIUFlOT1VGQUJNQURBTlpKQUVWSVNOT0hUWVBMQUFZTEJNRVNTQUNXRUlWQkFMT0dPTSIKCncyIOKGkCAiQkFDS1NQQUNFIuKAvyJCT0xEIuKAvyJDTE9TRSLigL8iQ09NUEFDVERJU0Mi4oC/IkNPUFki4oC/IkNQVSLigL8iQ1VSU09SIuKAvyJERUxFVEUi4oC/IkRFU0tUT1Ai4oC/IkRWRCLigL8iRURJVCLigL8iRU5URVIi4oC/IkVYSVQi4oC/IkZMT1BQWSLigL8iRk9OVCLigL8iSEFSRFdBUkUi4oC/IklOVEVSTkVUIuKAvyJLRVlCT0FSRCLigL8iTU9OSVRPUiLigL8iTU9VU0Ui4oC/IlBBU1NXT1JEIuKAvyJQQVNURSLigL8iUkVUVVJOIuKAvyJTQVZFIuKAvyJTT0ZUV0FSRSLigL8iU1RBUlQi4oC/IlRFWFQi4oC/IlRPV0VSIuKAvyJXT1JEUFJPQ0VTU0lORyIKZzIg4oaQIDE14oC/MTXipYoiSUFVRVJBV1RGT1NJQ1BOREdaUEZMT1BQWUFSRkxVUlNOT0NVUlNPUlZaREJNQU1OSVVPTVJOSEVHVUlOT1RCTlNSTU9OSVRPUk5UQkVZVFRTR1BKQk9MRFJUWVJRRUFIRUhBUkRXQVJFRU9HUlJORUNFQ0xPU0VQS0lPTlRZS1RPRFRPV0VSRUxDRU5TVVBFUlBES05OQVRSVFBSWUtFTFBWSUVKR0lFQU5QT1RLU0VEVVNMTlhDTVBBU1NXT1JEUlVDVEVESVRBR1ZTV0pDVE9WQ1dPWVBHWVFLTkxWWE1XIgoKKHcxIEYgZzEp4ouIKHcyIEYgZzIpCgo=)
```
{wùïäg:g‚äë‚àò‚ÜëÀú¬®¬Ø2+‚à®¬¥‚•äw{ ... }‚åú‚Üï4}
 wùïäg:                          # A dyadic function taking:
                               #  - left argument w: word list
                               #  - right argument g: grid
                          ‚Üï4   # 0 1 2 3
                  { ... }‚åú     # For each of those numbers on the right (specifying rotation) and ...
                 w             # each word on the left, call the inner function.
                               # The inner function returns boolean matrices of the same shape of the input
              ‚à®¬¥‚•ä              # Boolean OR of all the matrices
     g‚äë‚àò‚ÜëÀú¬®¬Ø2+                 # For 1's in the matrix take a character from the grid, for 0's take a space.
```
The inner function rotates the grid (as many times as its right argument specifies: `‚åΩ‚àò‚çâ‚çüùï©`), checks for words from left to right and on diagonals and then rotates the result back.
**How to get get diagonals**:
This method is mostly taken [from BQNcrate](https://mlochbaum.github.io/bqncrate/?q=diagonals%20into%20columns#). First a space is prepended to each row. Then each row is rotated by its index. Now words previously in the diagonals are in the columns, by transposing we get them in the rows. After marking the words, all the steps can be reversed: [Try with step-by-step results!](https://mlochbaum.github.io/BQN/try.html#code=c3RlcHMg4oaQICIx4oaTy5gi4oC/IuKKksuc4oy94oG8y5gi4oC/IsK34o2JIuKAvyLCt0jLmCLigL8iwrfijYki4oC/IuKKksuc4oy9y5gi4oC/IicgJ+KIvsuYIuKAvyLiiqIiCgp0ZXN0IOKGkCA+4p+oCiJ8fHx8IgoiQXx8fCIKInxEfHwiCiJ8fEF8Igrin6kKCj57ZuKGkOKAokJRTiAiSOKGkOKKksuc4oiKwrfipYoo4oaV4omgIiJBREEiIikr4oycwrcvIiJBREEiIuKKuOKNt+KLhCLiiL7wnZWp4ouE8J2VqeKLiEYgdGVzdH3CqCAx4oaT4oy94oi+wqjihpNzdGVwcwo=)
[Answer]
## Scala  697, 666  649
```
val(z,n)=io.Source.fromFile("F").getLines.toList.span(_.length>0)
val m=n.tail
val(w,h)=(m.head.length,m.size)
def g(d:Int,e:Int,k:Int,g:Int,h:Int,i:Int,s:String)={
def f(x:Int,y:Int):Seq[(Int,Int)]={
val q=for(c<-(0 to s.size-1))
yield (y+c*i,x+c*k)
if((q.map(p=>m(p._1)(p._2))).mkString==s)q else Nil}
val t=for(x<-(d to e);
y<-(g to h))yield f(x,y)
t.flatten}
def i(s:String)={val l=s.size
g(0,w-l,1,0,h-1,0,s)++ g(0,w-1,0,0,h-l,1,s)++ g(0,w-l,1,l-1,h-1,-1,s)++ g(0,w-l,1,0,h-l,1,s)}
def j(s: String)=i(s)++ i(s.reverse)
val k=z.map(j).flatten
(0 to h-1).map(r=>{(0 to w-1).map(c=>if(k.contains(r,c))print(""+m(r)(c))else print(" "));println()})
```
### degolfed:
```
object Golf {
def main (args: Array[String]) = {
  val (words, matrix) = io.Source.fromFile ("./wordsearch.data").getLines.toList.span (_.length > 0)
  val m = matrix.tail
  val (w,h) = (m.head.length, m.size)
  // xi: x-increment, yi: y-increment
  def find (x: Int, y: Int, xi: Int, yi: Int, s: String): Seq [(Int, Int)] = {
    val points = for (c <- (0 to s.length-1))
       yield (y + c*yi, x + c * xi)
    if ((points.map (p => m (p._1)(p._2))).mkString == s) points else Nil
  }
  def findInScope (xS: Int, xD: Int, xi: Int, yS: Int, yD: Int, yi: Int, s: String): Seq [(Int, Int)] = {
    val ppoints = for (x <- (xS to xD);
          y <- (yS to yD)) yield find (x, y, xi, yi, s)
    ppoints.flatten 
  }
  def findRowColFallingClimbing (s: String) = {
    val l=s.length
    // horizontal:
      findInScope (0,   w-l,  1,   0, h-1,  0, s) ++
    // vertical: 
      findInScope (0,   w-1,  0,   0, h-l,  1, s) ++
    // climbing /:
      findInScope (0,   w-l,  1, l-1, h-1, -1, s) ++
    // falling \:
      findInScope (0,   w-l,  1,   0, h-l,  1, s)
  }
  def findBoth (s: String) = findRowColFallingClimbing (s) ++ findRowColFallingClimbing (s.reverse)
  val coords = words.map (findBoth).flatten
  (0 to h-1).map ( r => {
    (0 to w-1).map (c =>
      if (coords.contains (r, c))
       print ("" + m(r)(c)) 
      else print (" ")
     )
     println ()
   })
  }
}
```
]