They both seem to be receiving & processing kernel events, so why do they both exist? From what I gather, ACPI seems to be more high-level compared to udev, but apart from that can't really tell.
ACPI is a low-level interface for mainboard vendors to provide information about built-in devices that cannot be (reliably) autodetected to the operating system. It also provides methods for power management and hardware monitoring to the kernel. One interesting thing ACPI provides are so called ACPI events. To create these, the hardware emits a special interrupt (the General Purpose Event Interrupt) when something happens on built in hardware and the kernel then calls the ACPI code which determines what happened on which built-in device. See the specification if you want to know how the whole thing works in detail.
acpid is a daemon that listens for the events generated by the ACPI subsystem in the kernel and allows to run commands when a specific event happened. For example if the hardware signaled via ACPI that the power button was pressed, you get an event on a device in the "button/power" class. The daemon can only react to these events generated via ACPI and not to events on e.g. the USB bus.
udev is a Linux-specific daemon that allows to react on changes in the device tree managed by the kernel. For example if you plug in an USB stick, the kernel is notified by the USB controller and a new device is added to the Linux device tree. Then the
usb_storage driver detects that the new device is a storage device and creates sub-device nodes in the tree that allow the user space to handle the USB stick like any other hard drive. If you plug it out, these devices are removed from the tree. udev is notified on each of these additions and removals. udev can also react to some events that aren't device additions/removals like opening/closing of a CD tray, but that's most of it. You can run
udevadm monitor --kernel to see what events udev gets in real time.
You can say that acpid and udev complement each other. udev is useful to react to major changes about any device the OS knows about, while acpid is useful to react to more specific events that happen to some built-in devices.