Here are some of the tools I use to create crosswords for The Tartan.
This program, written in Turbo Pascal 3.0, is used to design symmetrical 15x15 crossword grids from scratch. It has no-symmetry, 180-degree-symmetry, and 90-degree-symmetry modes. It also keeps track of word count, but doesn't try to prevent the user from creating two-letter entries or using an excess of black squares. These improvements are left as an exercise for the interested reader.
I don't use this program much anymore. Instead, I get my grids from other constructors' crosswords, and modify them as necessary to fit my themes. One good resource for this pursuit is The Washington Post's daily crossword archive: here.
This program, written in C, is a minimal crossword dictionary. It loads a text file of words at startup, and then can produce lists of those words that match wildcard specifications such as a??c?s or ?b*s. The 0 and 1 wildcard characters match vowels and consonants, respectively. The user can also add and remove words from the dictionary while it is running, using the ADD and REM commands. There is a SET command for finding out which letters can possibly fit in a given space; e.g., typing SET ab_??s produces "abehilmnouy".
I use this program to fill in grids, using the dictionary tartan.txt from the "Dictionaries" section below.
This program, written in C, is a crossword grid filler. It loads a text file of words at startup (the same file used by xdict), and then tries to use those words to fill in a grid supplied by the user in another file or via standard input. It does this by reducing the grid-filling problem to the exact cover problem, and then applying Donald Knuth's "Dancing Links" algorithm to generate the exact cover. It has some limitations, but it's basically sound.
This program, written in C, takes as input a completely filled-in crossword grid and produces various useful outputs, including numbered entry lists (horizontal and vertical one at a time, separately, or combined); a blank grid (with or without numbering placeholders); a solution grid without the black squares marked; and statistics such as the lengths of the longest entries, the average word length, the number of two-letter and unchecked entries, and the pangrammatic properties of the grid.
Most of this program's statistics also apply to blank grids; it can tell the number of unkeyed letters, for example, or the number of "cheaters" (black squares which don't change the word count).
I use this program to prepare my entry lists, and in conjunction with sort -k2 to make sure there are no duplicated entries.
This program, written in C, takes as input either a completely filled-in crossword grid à la xword-ent, or the output from xword-ent -SG -HV with clues and title filled in. It looks for three things: a title at the top of the input, a crossword grid, and lists of clues Across and Down. It produces the crossword and clues, nicely typeset using LaTeX.
This program's LaTeX code is heavily derivative of Gerd Neugebauer's cwpuzzle package for LaTeX. I've provided an option under which the LaTeX output will actually use cwpuzzle.sty (which must be downloaded elsewhere) instead of "raw" LaTeX commands... but I don't recommend it unless you are going to be editing the LaTeX output.
I use this program when I want to print out a nice copy of a crossword and don't have access to Adobe InDesign. It isn't meant to be completely robust.
There are several public-domain crossword dictionaries available on the Internet. Here is the one I use, and links to several others.