As mentioned in the other answer, quadtrees are a good choice.
R-Trees should also work well, they often cope better with clustered data but they tend to be slower to build or update. If you dataset changes, check out the R*tree, if you can bulk load it (no changes afterwards), check out the STR-Loaded R-Tree. If your R-Tree does not support point queries, just query for a rectangle which represents a point (all corners have the same coordinate).
If you are using Java, check you my PH-Tree. It's a bit like a quadtree, but copes better with clustered data. For containment queries it's speed depends on the average number of rectangles that contain a search-point. If there are usually few (less than 5-10) rectangles that contain your point, then it may be the fastest three you can find. If you expect 100 or 1000 of rectangles to overlap with your point, R-Trees may be better.
If you want to implement the structure yourself, quadtrees and kd-trees are probably simplest, R-Trees are harder, PH-Tree may be even more difficult to get right. Quadtrees are harder to get right than they look, because for large/clustered datasets you may quickly run into precision problems.
If you are using Java, have a look at my implementations of quadtree, R*Tree, STR-Tree and PH-Tree here (there is also a kd-tree, but it doesn't suppor rectangle entries, only points).