Of course, the additional spaces of the array/tabular can be minimized to zero:
\documentclass[12pt]{article}
\usepackage{amssymb}
\usepackage{color}
\setlength{\parskip}{1ex}
\begin{document}
$
\renewcommand*{\arraystretch}{0}
\begin{array}{@{}c@{}c@{}}
\square & \\
\square & \square
\end{array}
$
\begingroup
\renewcommand*{\arraystretch}{0}%
\setlength{\tabcolsep}{0pt}%
\setlength{\mathsurround}{0pt}%
\begin{tabular}{cc}
$\square$ &\\
$\square$ & $\square$
\end{tabular}%
\endgroup
\setlength{\fboxsep}{0pt}
\fbox{\textcolor{red}{$\square$}}
\end{document}

But that does not solve your problems:
The character box is larger than the character itself. The black \fbox frame is wider than the red \sqare. These white spaces are called left and right side bearings.
The values of these are unkown in TeX.
The upper line of the left lower box and the lower line of the upper box make a horizontal line with double line width. Also the line width of the glyph is not known in TeX.
Therefore I would do the drawing by graphics. An example for tikz that also allows rounded corners:
\documentclass[12pt]{article}
\usepackage{amssymb}
\usepackage{tikz}
\newdimen\squareunit
\newdimen\squarelinewidth
\newcommand*{\BaseSquare}[1]{%
\begingroup
\settoheight{\squareunit}{$\square$}%
\setlength{\squarelinewidth}{.055\squareunit}%
\addtolength{\squareunit}{-\squarelinewidth}%
\begin{tikzpicture}[
x=\squareunit,
y=\squareunit,
line width=\squarelinewidth,
line join=round,
]
\draw[line join=round]#1;%
\end{tikzpicture}%
\endgroup
}
\newcommand*{\Square}{%
\BaseSquare{(0,0) rectangle (1,1)}%
}
\newcommand*{\Ltromino}{%
\BaseSquare{%
(0,0) -- (2,0) -- (2,1) -- (1,1) -- (1,2) -- (0,2) -- cycle
(0,1) -- (1,1) -- (1,0)
}%
}
\newcommand*{\ltromino}{%
\BaseSquare{%
(0,0) -- (1,0) -- (1,3) -- (0,3) -- cycle
(0,1) -- (1,1)
(0,2) -- (1,2)
}%
}
\begin{document}
$\square$\,\Square\,\Ltromino\,\ltromino
\end{document}

youngtabpackage (and others) may be helpful, although overkill. – barbara beeton Dec 17 '12 at 15:14